HHH-3294 : persistent collection dirtiness on merge

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@14839 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2008-07-01 21:39:28 +00:00
parent f926cf3c34
commit ddfed3e999
2 changed files with 55 additions and 2 deletions

View File

@ -550,11 +550,15 @@ public abstract class CollectionType extends AbstractType implements Association
//the array length might not match //the array length might not match
result = replaceElements( original, result, owner, copyCache, session ); result = replaceElements( original, result, owner, copyCache, session );
if (original==target) { if ( original == target ) {
//get the elements back into the target // get the elements back into the target making sure to handle dirty flag
boolean wasClean = PersistentCollection.class.isInstance( target ) && !( ( PersistentCollection ) target ).isDirty();
//TODO: this is a little inefficient, don't need to do a whole //TODO: this is a little inefficient, don't need to do a whole
// deep replaceElements() call // deep replaceElements() call
replaceElements( result, target, owner, copyCache, session ); replaceElements( result, target, owner, copyCache, session );
if ( wasClean ) {
( ( PersistentCollection ) target ).clearDirty();
}
result = target; result = target;
} }

View File

@ -283,6 +283,55 @@ public class MergeTest extends AbstractOperationTestCase {
cleanup(); cleanup();
} }
public void testNoExtraUpdatesOnPersistentMergeVersionedWithCollection() throws Exception {
Session s = openSession();
s.beginTransaction();
VersionedEntity parent = new VersionedEntity( "parent", "parent" );
VersionedEntity child = new VersionedEntity( "child", "child" );
parent.getChildren().add( child );
child.setParent( parent );
s.persist( parent );
s.getTransaction().commit();
s.close();
clearCounts();
// parent is now detached, but we have made no changes. so attempt to merge it
// into this new session; this should cause no updates...
s = openSession();
s.beginTransaction();
// load parent so that merge will follow entityIsPersistent path
VersionedEntity persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
// load children
VersionedEntity persistentChild = ( VersionedEntity ) persistentParent.getChildren().iterator().next();
VersionedEntity mergedParent = ( VersionedEntity ) s.merge( persistentParent ); // <-- This merge leads to failure
s.getTransaction().commit();
s.close();
assertUpdateCount( 0 );
assertInsertCount( 0 );
assertEquals( "unexpected parent version increment", parent.getVersion(), mergedParent.getVersion() );
VersionedEntity mergedChild = ( VersionedEntity ) mergedParent.getChildren().iterator().next();
assertEquals( "unexpected child version increment", child.getVersion(), mergedChild.getVersion() );
///////////////////////////////////////////////////////////////////////
// as a control measure, now update the node once it is loaded and
// make sure we get an update as a result...
s = openSession();
s.beginTransaction();
persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
persistentParent.setName( "new name" );
persistentParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
persistentParent = ( VersionedEntity ) s.merge( persistentParent );
s.getTransaction().commit();
s.close();
assertUpdateCount( 1 );
assertInsertCount( 1 );
///////////////////////////////////////////////////////////////////////
// cleanup();
}
public void testPersistThenMergeInSameTxnWithVersion() { public void testPersistThenMergeInSameTxnWithVersion() {
Session s = openSession(); Session s = openSession();
Transaction tx = s.beginTransaction(); Transaction tx = s.beginTransaction();