Community
Participate
Working Groups
To reproduce: using fieldaccess.advanced model read an Employee that has an address; then copy it with CASCADE_ALL_PARTS cascade depth: CopyGroup group = new CopyGroup(); group.cascadeAllParts(); empCopy = (Employee)em.unwrap(JpaEntityManager.class).copy(emp, group); Result: both emp and empCopy have the same Address The original and the copy share the ValueHolder, therefore when the copy of the Address is assigned to copy Employee it also lands into the original. The culprit is PersistenceEntityCopyPolicy.buldClone method: public Object buildClone(Object object, Session session) throws DescriptorException { return ((PersistenceObject)object)._persistence_shallow_clone(); } _persistence_shallow_clone is a new method added by weaving: public Object _persistence_shallow_clone() { return super.clone(); } that's why value holders are shared by source and copy. Note that a similar problem is succefully resolved in a woven clone method, here's the woven code for org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee: public Employee clone() { try { return (Employee)((Employee)super.clone())._persistence_post_clone(); } catch(CloneNotSupportedException exception) { throw new InternalError(exception.toString()); } } where: public Object _persistence_post_clone() { if(_persistence_manager_vh != null) _persistence_manager_vh = (WeavedAttributeValueHolderInterface)_persistence_manager_vh.clone(); if(_persistence_address_vh != null) _persistence_address_vh = (WeavedAttributeValueHolderInterface)_persistence_address_vh.clone(); _persistence_listener = null; _persistence_fetchGroup = null; _persistence_session = null; _persistence_primaryKey = null; return this; } Suggested solution - add a similar method to _persistence_shallow_clone: public Object _persistence_shallow_clone() { return super.clone()._persistence_post_super_clone(); } public Object _persistence_post_super_clone() { _persistence_manager_vh = null; _persistence_address_vh = null; _persistence_listener = null; _persistence_fetchGroup = null; _persistence_session = null; _persistence_primaryKey = null; return this; } To test uncomment copyCascadeAllParts in org.eclipse.persistence.testing.tests.jpa.fetchgroups.SimpleSerializeFetchGroupTests: currently it fails with: junit.framework.AssertionFailedError: address has not been copied. After this bug is fixed the test should pass. Note that the same problem also affects PersistenceEntityCopyPolicy.buildWorkingCopyClone method.
Created attachment 174160 [details] suggested patch The shallow copy is working properly, the responsibility to clear the attributes woven into the class is on ObjectBuilder (instantiateClone method), to set a new ValueHolder - is on the corresponding mapping (ObjectReferenceMapping.getCopy).
Created attachment 174305 [details] updated patch Added calling reset on indirection policy for CollectionMapping and DirectCollectionMapping.
The patch checked into trunk, 2.1.1 is pending.
Backported to 2.1.1.
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink