How to ignore or not to copy property id from each hibernate persistent object or set to null otherwise I am getting this error while saving copied object using Hibernate3BeanReplicator
"a different object with the same identifier value was already associated with the session"
Thanks
Gopal
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You need to treat the cloned objects as "detached" objects in Hibernate to avoid such problem. For example, you can try to flush /clear the existing Hibernate session before updating using the cloned object.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What I was trying to do saving new objectB which was clone from ObjectA since objectA had generated id in it, even if I flush after cloning BUT when I will save objectB I will get a Unique contraint violation b'cos that Object unique id already exist in database.
I don't want to update existing ObjectA, What I wanted is to create new ObjectB clone from ObjectA and change some property values on ObjectB and save it.
Thanks for reply
Gopal
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
>What I wanted is to create new ObjectB clone from ObjectA and change some property values on ObjectB and save it.
In that case, wouldn't the simplest way be to set the id of ObjectB to null before saving it, since you need to change some property values on ObjectB anyway ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
yes, you are right I could change ObjectB id to null but only problem is it has deep object graph and I have many objects like ObjectB, some has one-to-one and some has one-to-many relation in it, may be 20-25.
So, to set each object id to null, I have to traverse the object graph. For now this feature is trivial
Thanks for your help, I will post more question if I encounter any issue
Gopal
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Defining your own BeanPopulatable would work. Alternatively you can define your own DetailedBeanPopulatable, which would give you more fine grained control.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I thought that the whole point of the Veto-er was such that it would remain null if you dont populate the assignable id property. Does this not work on a deep copy throughout the object graph?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am getting out of Memory error. My object graph is not that big. it has 24 collections. The error is appended.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.nio.CharBuffer.wrap(CharBuffer.java:350)
at java.nio.CharBuffer.wrap(CharBuffer.java:373)
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:138)
at java.lang.StringCoding.decode(StringCoding.java:173)
at java.lang.String.<init>(String.java:444)
at org.postgresql.core.Encoding.decode(Encoding.java:181)
at org.postgresql.core.Encoding.decode(Encoding.java:193)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getString(AbstractJdbc2ResultSet.java:1893)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getFixedString(AbstractJdbc2ResultSet.java:2386)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getInt(AbstractJdbc2ResultSet.java:1994)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getInt(AbstractJdbc2ResultSet.java:2208)
at org.hibernate.type.IntegerType.get(IntegerType.java:28)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:113)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:102)
at org.hibernate.type.ManyToOneType.hydrate(ManyToOneType.java:95)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:1899)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1372)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1300)
at org.hibernate.loader.Loader.getRow(Loader.java:1197)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:569)
at org.hibernate.loader.Loader.doQuery(Loader.java:689)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1919)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:520)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1676)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
at org.hibernate.Hibernate.initialize(Hibernate.java:295)
at net.sf.beanlib.hibernate3.Hibernate3BeanTransformer.hibernateInitialize(Hibernate3BeanTransformer.java:37)
at net.sf.beanlib.hibernate.HibernateBeanTransformer.replicateCollection(HibernateBeanTransformer.java:273)
at net.sf.beanlib.hibernate.HibernateBeanTransformer.replicate(HibernateBeanTransformer.java:150)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The transitive closure (ie object graph) of 24 collections can potentially be huge. Looks like the OOME is thrown due to the initialization of the collections. Do you really want to do a deep cone of the entire object graph ? If so, you may want to increase your heap size via the JVM parameter -Xmx. If not, you can filter out some collections from being copied instead of a straight deep copy. Check out the interface CollectionPropertyName.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In this interface I can only specify what collections to copy correct, or not to copy? Can I actually tell it what collections or entities to keep references to same as fromBean since they are lookup tables....that is what the intended behaviour I would want anyways, and it would cut down on the memory requirements bigtime.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
>In this interface I can only specify what collections to copy correct, or not to copy?
The former - ie what to copy.
>Can I actually tell it what collections or entities to keep references to same as fromBean since they are lookup tables
Keeping referecnes to the fromBean can be problematic as some of them may not have been initialized. However, if you really want to do that, you can consider defining your own CustomBeanTransformerSpi and see if that would work for you.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
How to ignore or not to copy property id from each hibernate persistent object or set to null otherwise I am getting this error while saving copied object using Hibernate3BeanReplicator
"a different object with the same identifier value was already associated with the session"
Thanks
Gopal
You need to treat the cloned objects as "detached" objects in Hibernate to avoid such problem. For example, you can try to flush /clear the existing Hibernate session before updating using the cloned object.
What I was trying to do saving new objectB which was clone from ObjectA since objectA had generated id in it, even if I flush after cloning BUT when I will save objectB I will get a Unique contraint violation b'cos that Object unique id already exist in database.
I don't want to update existing ObjectA, What I wanted is to create new ObjectB clone from ObjectA and change some property values on ObjectB and save it.
Thanks for reply
Gopal
>What I wanted is to create new ObjectB clone from ObjectA and change some property values on ObjectB and save it.
In that case, wouldn't the simplest way be to set the id of ObjectB to null before saving it, since you need to change some property values on ObjectB anyway ?
yes, you are right I could change ObjectB id to null but only problem is it has deep object graph and I have many objects like ObjectB, some has one-to-one and some has one-to-many relation in it, may be 20-25.
So, to set each object id to null, I have to traverse the object graph. For now this feature is trivial
Thanks for your help, I will post more question if I encounter any issue
Gopal
Hi,
A best way to do it is probably to define a Populatable that will just refuse bean population on property "id".
Just my 2 cents
Bruno
Defining your own BeanPopulatable would work. Alternatively you can define your own DetailedBeanPopulatable, which would give you more fine grained control.
I thought that the whole point of the Veto-er was such that it would remain null if you dont populate the assignable id property. Does this not work on a deep copy throughout the object graph?
You are right - vetoer is another option. It would certainly work on deep copy.
I am getting out of Memory error. My object graph is not that big. it has 24 collections. The error is appended.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.nio.CharBuffer.wrap(CharBuffer.java:350)
at java.nio.CharBuffer.wrap(CharBuffer.java:373)
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:138)
at java.lang.StringCoding.decode(StringCoding.java:173)
at java.lang.String.<init>(String.java:444)
at org.postgresql.core.Encoding.decode(Encoding.java:181)
at org.postgresql.core.Encoding.decode(Encoding.java:193)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getString(AbstractJdbc2ResultSet.java:1893)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getFixedString(AbstractJdbc2ResultSet.java:2386)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getInt(AbstractJdbc2ResultSet.java:1994)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getInt(AbstractJdbc2ResultSet.java:2208)
at org.hibernate.type.IntegerType.get(IntegerType.java:28)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:113)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:102)
at org.hibernate.type.ManyToOneType.hydrate(ManyToOneType.java:95)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:1899)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1372)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1300)
at org.hibernate.loader.Loader.getRow(Loader.java:1197)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:569)
at org.hibernate.loader.Loader.doQuery(Loader.java:689)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1919)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:520)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1676)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
at org.hibernate.Hibernate.initialize(Hibernate.java:295)
at net.sf.beanlib.hibernate3.Hibernate3BeanTransformer.hibernateInitialize(Hibernate3BeanTransformer.java:37)
at net.sf.beanlib.hibernate.HibernateBeanTransformer.replicateCollection(HibernateBeanTransformer.java:273)
at net.sf.beanlib.hibernate.HibernateBeanTransformer.replicate(HibernateBeanTransformer.java:150)
The transitive closure (ie object graph) of 24 collections can potentially be huge. Looks like the OOME is thrown due to the initialization of the collections. Do you really want to do a deep cone of the entire object graph ? If so, you may want to increase your heap size via the JVM parameter -Xmx. If not, you can filter out some collections from being copied instead of a straight deep copy. Check out the interface CollectionPropertyName.
In this interface I can only specify what collections to copy correct, or not to copy? Can I actually tell it what collections or entities to keep references to same as fromBean since they are lookup tables....that is what the intended behaviour I would want anyways, and it would cut down on the memory requirements bigtime.
>In this interface I can only specify what collections to copy correct, or not to copy?
The former - ie what to copy.
>Can I actually tell it what collections or entities to keep references to same as fromBean since they are lookup tables
Keeping referecnes to the fromBean can be problematic as some of them may not have been initialized. However, if you really want to do that, you can consider defining your own CustomBeanTransformerSpi and see if that would work for you.