//$Id: MergeTest.java 11037 2007-01-09 16:04:16Z steve.ebersole@jboss.com $
package org.hibernate.test.nonflushedchanges;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.Session;
import org.hibernate.StaleObjectStateException;
import org.hibernate.criterion.Projections;
import org.junit.Test;
import org.hibernate.testing.jta.TestingJtaBootstrap;
import static org.junit.Assert.*;
/**
* adapted this from "ops" tests version
*
* @author Gail Badner
* @author Gavin King
*/
public class MergeTest extends AbstractOperationTestCase {
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testMergeStaleVersionFails() throws Exception {
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
VersionedEntity entity = new VersionedEntity( "entity", "entity" );
s.persist( entity );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
// make the detached 'entity' reference stale...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
VersionedEntity entity2 = ( VersionedEntity ) s.get( VersionedEntity.class, entity.getId() );
entity2.setName( "entity-name" );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
// now try to reattach it
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
try {
s.merge( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
entity = ( VersionedEntity ) getOldToNewEntityRefMap().get( entity );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
fail( "was expecting staleness error" );
}
catch ( StaleObjectStateException expected ) {
// expected outcome...
}
finally {
TestingJtaBootstrap.INSTANCE.getTransactionManager().rollback();
}
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testMergeBidiPrimayKeyOneToOne() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Person p = new Person( "steve" );
new PersonalDetails( "I have big feet", p );
s.persist( p );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
clearCounts();
p.getDetails().setSomePersonalDetail( p.getDetails().getSomePersonalDetail() + " and big hands too" );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
p = ( Person ) s.merge( p );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
p = ( Person ) getOldToNewEntityRefMap().get( p );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 0 );
assertUpdateCount( 1 );
assertDeleteCount( 0 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.delete( p );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testMergeBidiForeignKeyOneToOne() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Person p = new Person( "steve" );
Address a = new Address( "123 Main", "Austin", "US", p );
s.persist( a );
s.persist( p );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
clearCounts();
p.getAddress().setStreetAddress( "321 Main" );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
p = ( Person ) s.merge( p );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 ); // no cascade
assertDeleteCount( 0 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.delete( a );
s.delete( p );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testNoExtraUpdatesOnMerge() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Node node = new Node( "test" );
s.persist( node );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
clearCounts();
// node is now detached, but we have made no changes. so attempt to merge it
// into this new session; this should cause no updates...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
node = ( Node ) s.merge( node );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 0 );
assertInsertCount( 0 );
///////////////////////////////////////////////////////////////////////
// as a control measure, now update the node while it is detached and
// make sure we get an update as a result...
node.setDescription( "new description" );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
node = ( Node ) s.merge( node );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 1 );
assertInsertCount( 0 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
@Test
@SuppressWarnings( {"unchecked", "UnusedAssignment"})
public void testNoExtraUpdatesOnMergeWithCollection() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Node parent = new Node( "parent" );
Node child = new Node( "child" );
parent.getChildren().add( child );
child.setParent( parent );
s.persist( parent );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
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...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
parent = ( Node ) s.merge( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 0 );
assertInsertCount( 0 );
///////////////////////////////////////////////////////////////////////
// as a control measure, now update the node while it is detached and
// make sure we get an update as a result...
( ( Node ) parent.getChildren().iterator().next() ).setDescription( "child's new description" );
parent.addChild( new Node( "second child" ) );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
parent = ( Node ) s.merge( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 1 );
assertInsertCount( 1 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testNoExtraUpdatesOnMergeVersioned() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
VersionedEntity entity = new VersionedEntity( "entity", "entity" );
s.persist( entity );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
clearCounts();
// entity is now detached, but we have made no changes. so attempt to merge it
// into this new session; this should cause no updates...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
VersionedEntity mergedEntity = ( VersionedEntity ) s.merge( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
mergedEntity = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedEntity );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 0 );
assertInsertCount( 0 );
assertEquals( "unexpected version increment", entity.getVersion(), mergedEntity.getVersion() );
///////////////////////////////////////////////////////////////////////
// as a control measure, now update the node while it is detached and
// make sure we get an update as a result...
entity.setName( "new name" );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
entity = ( VersionedEntity ) s.merge( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 1 );
assertInsertCount( 0 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
@Test
@SuppressWarnings( {"unchecked", "UnusedAssignment"})
public void testNoExtraUpdatesOnMergeVersionedWithCollection() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
VersionedEntity parent = new VersionedEntity( "parent", "parent" );
VersionedEntity child = new VersionedEntity( "child", "child" );
parent.getChildren().add( child );
child.setParent( parent );
s.persist( parent );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
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...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
VersionedEntity mergedParent = ( VersionedEntity ) s.merge( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
mergedParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedParent );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
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 while it is detached and
// make sure we get an update as a result...
mergedParent.setName( "new name" );
mergedParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
parent = ( VersionedEntity ) s.merge( mergedParent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
parent = ( VersionedEntity ) getOldToNewEntityRefMap().get( parent );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 1 );
assertInsertCount( 1 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
@Test
@SuppressWarnings( {"unchecked", "UnusedAssignment"})
public void testNoExtraUpdatesOnPersistentMergeVersionedWithCollection() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
VersionedEntity parent = new VersionedEntity( "parent", "parent" );
VersionedEntity child = new VersionedEntity( "child", "child" );
parent.getChildren().add( child );
child.setParent( parent );
s.persist( parent );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
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...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
// load parent so that merge will follow entityIsPersistent path
VersionedEntity persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
persistentParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( persistentParent );
// load children
persistentParent.getChildren().iterator().next();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
persistentParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( persistentParent );
VersionedEntity mergedParent = ( VersionedEntity ) s.merge( persistentParent ); // <-- This merge leads to failure
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
mergedParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedParent );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
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...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
persistentParent.setName( "new name" );
persistentParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
persistentParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( persistentParent );
persistentParent = ( VersionedEntity ) s.merge( persistentParent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertUpdateCount( 1 );
assertInsertCount( 1 );
///////////////////////////////////////////////////////////////////////
// cleanup();
}
@Test
public void testPersistThenMergeInSameTxnWithVersion() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
VersionedEntity entity = new VersionedEntity( "test", "test" );
s.persist( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.merge( new VersionedEntity( "test", "test-2" ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
try {
// control operation...
s.saveOrUpdate( new VersionedEntity( "test", "test-3" ) );
fail( "saveOrUpdate() should fail here" );
}
catch ( NonUniqueObjectException expected ) {
// expected behavior
}
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@Test
public void testPersistThenMergeInSameTxnWithTimestamp() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
TimestampedEntity entity = new TimestampedEntity( "test", "test" );
s.persist( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.merge( new TimestampedEntity( "test", "test-2" ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
try {
// control operation...
s.saveOrUpdate( new TimestampedEntity( "test", "test-3" ) );
fail( "saveOrUpdate() should fail here" );
}
catch ( NonUniqueObjectException expected ) {
// expected behavior
}
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testMergeDeepTree() throws Exception {
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Node root = new Node( "root" );
Node child = new Node( "child" );
Node grandchild = new Node( "grandchild" );
root.addChild( child );
child.addChild( grandchild );
s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 3 );
assertUpdateCount( 0 );
clearCounts();
grandchild.setDescription( "the grand child" );
Node grandchild2 = new Node( "grandchild2" );
child.addChild( grandchild2 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 1 );
assertUpdateCount( 1 );
clearCounts();
Node child2 = new Node( "child2" );
Node grandchild3 = new Node( "grandchild3" );
child2.addChild( grandchild3 );
root.addChild( child2 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.delete( grandchild );
s.delete( grandchild2 );
s.delete( grandchild3 );
s.delete( child );
s.delete( child2 );
s.delete( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testMergeDeepTreeWithGeneratedId() throws Exception {
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
NumberedNode child = new NumberedNode( "child" );
NumberedNode grandchild = new NumberedNode( "grandchild" );
root.addChild( child );
child.addChild( grandchild );
root = ( NumberedNode ) s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 3 );
assertUpdateCount( 0 );
clearCounts();
child = ( NumberedNode ) root.getChildren().iterator().next();
grandchild = ( NumberedNode ) child.getChildren().iterator().next();
grandchild.setDescription( "the grand child" );
NumberedNode grandchild2 = new NumberedNode( "grandchild2" );
child.addChild( grandchild2 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
root = ( NumberedNode ) s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 1 );
assertUpdateCount( 1 );
clearCounts();
sessionFactory().getCache().evictEntityRegion( NumberedNode.class );
NumberedNode child2 = new NumberedNode( "child2" );
NumberedNode grandchild3 = new NumberedNode( "grandchild3" );
child2.addChild( grandchild3 );
root.addChild( child2 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
root = ( NumberedNode ) s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.createQuery( "delete from NumberedNode where name like 'grand%'" ).executeUpdate();
s.createQuery( "delete from NumberedNode where name like 'child%'" ).executeUpdate();
s.createQuery( "delete from NumberedNode" ).executeUpdate();
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testMergeTree() throws Exception {
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Node root = new Node( "root" );
Node child = new Node( "child" );
root.addChild( child );
s.persist( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
child = ( Node ) root.getChildren().iterator().next();
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 2 );
clearCounts();
root.setDescription( "The root node" );
child.setDescription( "The child node" );
Node secondChild = new Node( "second child" );
root.addChild( secondChild );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.merge( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 1 );
assertUpdateCount( 2 );
cleanup();
}
@Test
@SuppressWarnings( {"UnusedAssignment"})
public void testMergeTreeWithGeneratedId() throws Exception {
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
NumberedNode child = new NumberedNode( "child" );
root.addChild( child );
s.persist( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
child = ( NumberedNode ) root.getChildren().iterator().next();
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 2 );
clearCounts();
root.setDescription( "The root node" );
child.setDescription( "The child node" );
NumberedNode secondChild = new NumberedNode( "second child" );
root.addChild( secondChild );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.merge( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 1 );
assertUpdateCount( 2 );
cleanup();
}
@Test
@SuppressWarnings( {"UnusedAssignment", "UnnecessaryBoxing"})
public void testMergeManaged() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
s.persist( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
clearCounts();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
NumberedNode child = new NumberedNode( "child" );
root = ( NumberedNode ) s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
root.addChild( child );
assertSame( root, s.merge( root ) );
Object mergedChild = root.getChildren().iterator().next();
assertNotSame( mergedChild, child );
assertTrue( s.contains( mergedChild ) );
assertFalse( s.contains( child ) );
assertEquals( root.getChildren().size(), 1 );
assertTrue( root.getChildren().contains( mergedChild ) );
//assertNotSame( mergedChild, s.merge(child) ); //yucky :(
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
mergedChild = root.getChildren().iterator().next();
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 1 );
assertUpdateCount( 0 );
assertEquals( root.getChildren().size(), 1 );
assertTrue( root.getChildren().contains( mergedChild ) );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
assertEquals(
Long.valueOf( 2 ),
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult()
);
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testMergeManagedUninitializedCollection() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
root.addChild( new NumberedNode( "child" ) );
s.persist( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
clearCounts();
NumberedNode newRoot = new NumberedNode( "root" );
newRoot.setId( root.getId() );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
Set managedChildren = root.getChildren();
assertFalse( Hibernate.isInitialized( managedChildren ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
managedChildren = root.getChildren();
newRoot.setChildren( managedChildren );
assertSame( root, s.merge( newRoot ) );
assertSame( managedChildren, root.getChildren() );
assertFalse( Hibernate.isInitialized( managedChildren ) );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 );
assertDeleteCount( 0 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
assertEquals(
Long.valueOf( 2 ),
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult()
);
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing"})
public void testMergeManagedInitializedCollection() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
root.addChild( new NumberedNode( "child" ) );
s.persist( root );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
clearCounts();
NumberedNode newRoot = new NumberedNode( "root" );
newRoot.setId( root.getId() );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
Set managedChildren = root.getChildren();
Hibernate.initialize( managedChildren );
assertTrue( Hibernate.isInitialized( managedChildren ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
managedChildren = root.getChildren();
newRoot.setChildren( managedChildren );
assertSame( root, s.merge( newRoot ) );
assertSame( managedChildren, root.getChildren() );
assertTrue( Hibernate.isInitialized( managedChildren ) );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 );
assertDeleteCount( 0 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
assertEquals(
Long.valueOf( 2 ),
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult()
);
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@Test
@SuppressWarnings( {"unchecked"})
public void testRecursiveMergeTransient() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Employer jboss = new Employer();
Employee gavin = new Employee();
jboss.setEmployees( new ArrayList() );
jboss.getEmployees().add( gavin );
s.merge( jboss );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.flush();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
jboss = ( Employer ) s.createQuery( "from Employer e join fetch e.employees" ).uniqueResult();
assertTrue( Hibernate.isInitialized( jboss.getEmployees() ) );
assertEquals( 1, jboss.getEmployees().size() );
s.clear();
s.merge( jboss.getEmployees().iterator().next() );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@Test
@SuppressWarnings( {"UnnecessaryBoxing", "UnusedAssignment"})
public void testDeleteAndMerge() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Employer jboss = new Employer();
s.persist( jboss );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
Employer otherJboss;
otherJboss = ( Employer ) s.get( Employer.class, jboss.getId() );
s.delete( otherJboss );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
jboss.setVers( Integer.valueOf( 1 ) );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
s.merge( jboss );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@Test
@SuppressWarnings( {"unchecked", "UnusedAssignment"})
public void testMergeManyToManyWithCollectionDeference() throws Exception {
// setup base data...
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
Competition competition = new Competition();
competition.getCompetitors().add( new Competitor( "Name" ) );
competition.getCompetitors().add( new Competitor() );
competition.getCompetitors().add( new Competitor() );
s.persist( competition );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
// the competition graph is now detached:
// 1) create a new List reference to represent the competitors
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
List newComp = new ArrayList();
Competitor originalCompetitor = ( Competitor ) competition.getCompetitors().get( 0 );
originalCompetitor.setName( "Name2" );
newComp.add( originalCompetitor );
newComp.add( new Competitor() );
// 2) set that new List reference unto the Competition reference
competition.setCompetitors( newComp );
// 3) attempt the merge
Competition competition2 = ( Competition ) s.merge( competition );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
Competition competition2copy = ( Competition ) getOldToNewEntityRefMap().get( competition2 );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
assertFalse( competition == competition2 );
assertFalse( competition2 == competition2copy );
assertFalse( competition.getCompetitors() == competition2.getCompetitors() );
assertEquals( 2, competition2.getCompetitors().size() );
assertEquals( 2, competition2copy.getCompetitors().size() );
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
s = openSession();
competition = ( Competition ) s.get( Competition.class, competition.getId() );
assertEquals( 2, competition.getCompetitors().size() );
s.delete( competition );
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
cleanup();
}
@SuppressWarnings( {"unchecked"})
private void cleanup() throws Exception {
TestingJtaBootstrap.INSTANCE.getTransactionManager().begin();
Session s = openSession();
s.createQuery( "delete from NumberedNode where parent is not null" ).executeUpdate();
s.createQuery( "delete from NumberedNode" ).executeUpdate();
s.createQuery( "delete from Node where parent is not null" ).executeUpdate();
s.createQuery( "delete from Node" ).executeUpdate();
s.createQuery( "delete from VersionedEntity where parent is not null" ).executeUpdate();
s.createQuery( "delete from VersionedEntity" ).executeUpdate();
s.createQuery( "delete from TimestampedEntity" ).executeUpdate();
s.createQuery( "delete from Competitor" ).executeUpdate();
s.createQuery( "delete from Competition" ).executeUpdate();
for ( Employer employer : (List<Employer>)s.createQuery( "from Employer" ).list() ) {
s.delete( employer );
}
TestingJtaBootstrap.INSTANCE.getTransactionManager().commit();
}
}