HHH-2762 : new unit tests for SessionImplementor.getNonFlushedChanges()/applyNonFlushedChanges() implementation

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17998 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2009-11-17 23:17:25 +00:00
parent 36100c8c3a
commit 01a1a251d7
22 changed files with 2738 additions and 0 deletions

View File

@ -0,0 +1,130 @@
package org.hibernate.test.nonflushedchanges;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.EntityKey;
import org.hibernate.engine.NonFlushedChanges;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.StatefulPersistenceContext;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.test.tm.ConnectionProviderImpl;
import org.hibernate.test.tm.TransactionManagerLookupImpl;
import org.hibernate.transaction.CMTTransactionFactory;
import org.hibernate.util.SerializationHelper;
/**
* {@inheritDoc}
*
* @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
*/
public abstract class AbstractOperationTestCase extends FunctionalTestCase {
private Map oldToNewEntityRefs = new HashMap();
public AbstractOperationTestCase(String name) {
super( name );
}
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.CONNECTION_PROVIDER, ConnectionProviderImpl.class.getName() );
cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, TransactionManagerLookupImpl.class.getName() );
cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() );
cfg.setProperty( Environment.AUTO_CLOSE_SESSION, "true" );
cfg.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "true" );
cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
}
public String[] getMappings() {
return new String[] {
"nonflushedchanges/Node.hbm.xml",
"nonflushedchanges/Employer.hbm.xml",
"nonflushedchanges/OptLockEntity.hbm.xml",
"nonflushedchanges/OneToOne.hbm.xml",
"nonflushedchanges/Competition.hbm.xml"
};
}
public String getCacheConcurrencyStrategy() {
return null;
}
protected void clearCounts() {
getSessions().getStatistics().clear();
}
protected void assertInsertCount(int expected) {
int inserts = ( int ) getSessions().getStatistics().getEntityInsertCount();
assertEquals( "unexpected insert count", expected, inserts );
}
protected void assertUpdateCount(int expected) {
int updates = ( int ) getSessions().getStatistics().getEntityUpdateCount();
assertEquals( "unexpected update counts", expected, updates );
}
protected void assertDeleteCount(int expected) {
int deletes = ( int ) getSessions().getStatistics().getEntityDeleteCount();
assertEquals( "unexpected delete counts", expected, deletes );
}
protected void assertFetchCount(int count) {
int fetches = ( int ) getSessions().getStatistics().getEntityFetchCount();
assertEquals( count, fetches );
}
protected Session applyNonFlushedChangesToNewSessionCloseOldSession(Session oldSession) {
NonFlushedChanges nfc = ( ( SessionImplementor ) oldSession ).getNonFlushedChanges();
byte[] bytes = SerializationHelper.serialize( nfc );
NonFlushedChanges nfc2 = ( NonFlushedChanges ) SerializationHelper.deserialize( bytes );
Session newSession = openSession();
( ( SessionImplementor ) newSession ).applyNonFlushedChanges( nfc2 );
oldToNewEntityRefs.clear();
for ( Iterator it = ( ( SessionImplementor ) oldSession ).getPersistenceContext()
.getEntitiesByKey()
.entrySet()
.iterator(); it.hasNext(); ) {
Map.Entry entry = ( Map.Entry ) it.next();
EntityKey entityKey = ( EntityKey ) entry.getKey();
Object oldEntityRef = entry.getValue();
oldToNewEntityRefs.put(
oldEntityRef, ( ( SessionImplementor ) newSession ).getPersistenceContext().getEntity( entityKey )
);
}
for ( Iterator it = ( ( StatefulPersistenceContext ) ( ( SessionImplementor ) oldSession ).getPersistenceContext() )
.getProxiesByKey()
.entrySet()
.iterator(); it.hasNext(); ) {
Map.Entry entry = ( Map.Entry ) it.next();
EntityKey entityKey = ( EntityKey ) entry.getKey();
Object oldProxyRef = entry.getValue();
oldToNewEntityRefs.put(
oldProxyRef, ( ( SessionImplementor ) newSession ).getPersistenceContext().getProxy( entityKey )
);
}
oldSession.clear();
oldSession.close();
return newSession;
}
protected void applyNonFlushedChangesToClearedSession(Session s) {
NonFlushedChanges nfc = ( ( SessionImplementor ) s ).getNonFlushedChanges();
byte[] bytes = SerializationHelper.serialize( nfc );
NonFlushedChanges nfc2 = ( NonFlushedChanges ) SerializationHelper.deserialize( bytes );
s.clear();
( ( SessionImplementor ) s ).applyNonFlushedChanges( nfc2 );
}
protected Map getOldToNewEntityRefMap() {
return Collections.unmodifiableMap( oldToNewEntityRefs );
}
}

View File

@ -0,0 +1,67 @@
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
/**
* {@inheritDoc}
*
* @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
*/
public class Address implements Serializable {
private Long id;
private String streetAddress;
private String city;
private String country;
private Person resident;
public Address() {
}
public Address(String streetAddress, String city, String country, Person resident) {
this.streetAddress = streetAddress;
this.city = city;
this.country = country;
this.resident = resident;
resident.setAddress( this );
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStreetAddress() {
return streetAddress;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Person getResident() {
return resident;
}
public void setResident(Person resident) {
this.resident = resident;
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
-->
<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
<class name="Competition">
<id name="id">
<generator class="native"/>
</id>
<list name="competitors" table="COMPET_ION_OR" cascade="persist,merge,delete">
<key column="TION_ID"/>
<list-index column="INDEX_COL"/>
<many-to-many class="Competitor" column="TOR_ID"/>
</list>
</class>
<class name="Competitor">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,32 @@
//$Id: $
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
*/
public class Competition implements Serializable {
private Integer id;
private List competitors = new ArrayList();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List getCompetitors() {
return competitors;
}
public void setCompetitors(List competitors) {
this.competitors = competitors;
}
}

View File

@ -0,0 +1,36 @@
//$Id: $
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
/**
* @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
*/
public class Competitor implements Serializable {
public Integer id;
private String name;
public Competitor() {
}
public Competitor(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,250 @@
//$Id: CreateTest.java 10977 2006-12-12 23:28:04Z steve.ebersole@jboss.com $
package org.hibernate.test.nonflushedchanges;
import java.util.ArrayList;
import java.util.Collection;
import junit.framework.Test;
import org.hibernate.Hibernate;
import org.hibernate.PersistentObjectException;
import org.hibernate.Session;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
/**
* @author Gavin King, Gail Badner (adapted this from "ops" tests version)
*/
public class CreateTest extends AbstractOperationTestCase {
public CreateTest(String str) {
super( str );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( CreateTest.class );
}
public void testNoUpdatesOnCreateVersionedWithCollection() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
VersionedEntity root = new VersionedEntity( "root", "root" );
VersionedEntity child = new VersionedEntity( "c1", "child-1" );
root.getChildren().add( child );
child.setParent( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.save( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( VersionedEntity ) getOldToNewEntityRefMap().get( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( VersionedEntity ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
assertDeleteCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.delete( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( VersionedEntity ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
public void testCreateTree() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node root = new Node( "root" );
Node child = new Node( "child" );
root.addChild( child );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.persist( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
System.out.println( "getting" );
root = ( Node ) s.get( Node.class, "root" );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
Node child2 = new Node( "child2" );
root.addChild( child2 );
System.out.println( "committing" );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 3 );
assertUpdateCount( 0 );
}
public void testCreateTreeWithGeneratedId() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
NumberedNode child = new NumberedNode( "child" );
root.addChild( child );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.persist( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) s.get( NumberedNode.class, new Long( root.getId() ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
NumberedNode child2 = new NumberedNode( "child2" );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
root.addChild( child2 );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 3 );
assertUpdateCount( 0 );
}
public void testCreateException() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node dupe = new Node( "dupe" );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.persist( dupe );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
dupe = ( Node ) getOldToNewEntityRefMap().get( dupe );
s.persist( dupe );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.persist( dupe );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
try {
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertFalse( true );
}
catch ( ConstraintViolationException cve ) {
//verify that an exception is thrown!
}
SimpleJtaTransactionManagerImpl.getInstance().rollback();
Node nondupe = new Node( "nondupe" );
nondupe.addChild( dupe );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.persist( nondupe );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
try {
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertFalse( true );
}
catch ( ConstraintViolationException cve ) {
//verify that an exception is thrown!
}
SimpleJtaTransactionManagerImpl.getInstance().rollback();
}
public void testCreateExceptionWithGeneratedId() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode dupe = new NumberedNode( "dupe" );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.persist( dupe );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
dupe = ( NumberedNode ) getOldToNewEntityRefMap().get( dupe );
s.persist( dupe );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
try {
s.persist( dupe );
assertFalse( true );
}
catch ( PersistentObjectException poe ) {
//verify that an exception is thrown!
}
SimpleJtaTransactionManagerImpl.getInstance().rollback();
NumberedNode nondupe = new NumberedNode( "nondupe" );
nondupe.addChild( dupe );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
try {
s.persist( nondupe );
assertFalse( true );
}
catch ( PersistentObjectException poe ) {
//verify that an exception is thrown!
}
SimpleJtaTransactionManagerImpl.getInstance().rollback();
}
public void testBasic() throws Exception {
Session s;
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
Employer er = new Employer();
Employee ee = new Employee();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.persist( ee );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
ee = ( Employee ) getOldToNewEntityRefMap().get( ee );
Collection erColl = new ArrayList();
Collection eeColl = new ArrayList();
erColl.add( ee );
eeColl.add( er );
er.setEmployees( erColl );
ee.setEmployers( eeColl );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
ee = ( Employee ) getOldToNewEntityRefMap().get( ee );
er = ( Employer ) ee.getEmployers().iterator().next();
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
er = ( Employer ) s.load( Employer.class, er.getId() );
assertNotNull( er );
assertFalse( Hibernate.isInitialized( er ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
er = ( Employer ) getOldToNewEntityRefMap().get( er );
assertNotNull( er );
assertFalse( Hibernate.isInitialized( er ) );
assertNotNull( er.getEmployees() );
assertEquals( 1, er.getEmployees().size() );
Employee eeFromDb = ( Employee ) er.getEmployees().iterator().next();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
eeFromDb = ( Employee ) getOldToNewEntityRefMap().get( eeFromDb );
assertEquals( ee.getId(), eeFromDb.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
}

View File

@ -0,0 +1,94 @@
package org.hibernate.test.nonflushedchanges;
import junit.framework.Test;
import org.hibernate.Session;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
/**
* {@inheritDoc}
*
* @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
*/
public class DeleteTest extends AbstractOperationTestCase {
public DeleteTest(String name) {
super( name );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( DeleteTest.class );
}
public void testDeleteVersionedWithCollectionNoUpdate() throws Exception {
// test adapted from HHH-1564...
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
VersionedEntity c = new VersionedEntity( "c1", "child-1" );
VersionedEntity p = new VersionedEntity( "root", "root" );
p.getChildren().add( c );
c.setParent( p );
s.save( p );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
VersionedEntity loadedParent = ( VersionedEntity ) s.get( VersionedEntity.class, "root" );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
loadedParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( loadedParent );
s.delete( loadedParent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 );
assertDeleteCount( 2 );
}
public void testNoUpdateOnDelete() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node node = new Node( "test" );
s.persist( node );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
s.delete( node );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 0 );
assertInsertCount( 0 );
}
public void testNoUpdateOnDeleteWithCollection() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node parent = new Node( "parent" );
Node child = new Node( "child" );
parent.getCascadingChildren().add( child );
s.persist( parent );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
parent = ( Node ) s.get( Node.class, "parent" );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
parent = ( Node ) getOldToNewEntityRefMap().get( parent );
s.delete( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 0 );
assertInsertCount( 0 );
assertDeleteCount( 2 );
}
}

View File

@ -0,0 +1,35 @@
//$Id: Employee.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
import java.util.Collection;
/**
* Employee in an Employer-Employee relationship
*
* @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
*/
public class Employee implements Serializable {
private Integer id;
private Collection employers;
public Integer getId() {
return id;
}
public void setId(Integer integer) {
id = integer;
}
public Collection getEmployers() {
return employers;
}
public void setEmployers(Collection employers) {
this.employers = employers;
}
}

View File

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
-->
<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
<class name="Employer" polymorphism="explicit">
<id name="id">
<generator class="native"/>
</id>
<version column="vers" name="vers"/>
<bag name="employees"
cascade="persist,merge"
table="EMPLOYER_EMPLOYEE">
<key column="EMPER_ID"/>
<many-to-many class="Employee" column="EMPEE_ID"/>
</bag>
</class>
<class name="Employee" polymorphism="explicit">
<id name="id">
<generator class="native"/>
</id>
<bag name="employers"
inverse="true"
cascade="persist,merge,save-update"
table="EMPLOYER_EMPLOYEE">
<key column="EMPEE_ID"/>
<many-to-many class="Employer" column="EMPER_ID"/>
</bag>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,44 @@
//$Id: Employer.java 8670 2005-11-25 17:36:29Z epbernard $
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
import java.util.Collection;
/**
* Employer in a employer-Employee relationship
*
* @author Emmanuel Bernard, Gail Badner (adapted this from "ops" tests version)
*/
public class Employer implements Serializable {
private Integer id;
private Collection employees;
private Integer vers;
public Integer getVers() {
return vers;
}
public void setVers(Integer vers) {
this.vers = vers;
}
public Collection getEmployees() {
return employees;
}
public Integer getId() {
return id;
}
public void setEmployees(Collection set) {
employees = set;
}
public void setId(Integer integer) {
id = integer;
}
}

View File

@ -0,0 +1,126 @@
//$Id: GetLoadTest.java 10977 2006-12-12 23:28:04Z steve.ebersole@jboss.com $
package org.hibernate.test.nonflushedchanges;
import junit.framework.Test;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
/**
* @author Gavin King, Gail Badner (adapted this from "ops" tests version)
*/
public class GetLoadTest extends AbstractOperationTestCase {
public GetLoadTest(String str) {
super( str );
}
public void testGetLoad() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Employer emp = new Employer();
s.persist( emp );
Node node = new Node( "foo" );
Node parent = new Node( "bar" );
parent.addChild( node );
s.persist( parent );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
emp = ( Employer ) s.get( Employer.class, emp.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
assertTrue( Hibernate.isInitialized( emp ) );
assertFalse( Hibernate.isInitialized( emp.getEmployees() ) );
node = ( Node ) s.get( Node.class, node.getName() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
node = ( Node ) getOldToNewEntityRefMap().get( node );
emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
assertTrue( Hibernate.isInitialized( node ) );
assertFalse( Hibernate.isInitialized( node.getChildren() ) );
assertFalse( Hibernate.isInitialized( node.getParent() ) );
assertNull( s.get( Node.class, "xyz" ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
emp = ( Employer ) s.load( Employer.class, emp.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
emp.getId();
assertFalse( Hibernate.isInitialized( emp ) );
node = ( Node ) s.load( Node.class, node.getName() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
node = ( Node ) getOldToNewEntityRefMap().get( node );
assertEquals( node.getName(), "foo" );
assertFalse( Hibernate.isInitialized( node ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
emp = ( Employer ) s.get( "org.hibernate.test.nonflushedchanges.Employer", emp.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
assertTrue( Hibernate.isInitialized( emp ) );
node = ( Node ) s.get( "org.hibernate.test.nonflushedchanges.Node", node.getName() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
node = ( Node ) getOldToNewEntityRefMap().get( node );
assertTrue( Hibernate.isInitialized( node ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
emp = ( Employer ) s.load( "org.hibernate.test.nonflushedchanges.Employer", emp.getId() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
emp.getId();
assertFalse( Hibernate.isInitialized( emp ) );
node = ( Node ) s.load( "org.hibernate.test.nonflushedchanges.Node", node.getName() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
emp = ( Employer ) getOldToNewEntityRefMap().get( emp );
node = ( Node ) getOldToNewEntityRefMap().get( node );
assertEquals( node.getName(), "foo" );
assertFalse( Hibernate.isInitialized( node ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertFetchCount( 0 );
}
public void testGetAfterDelete() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Employer emp = new Employer();
s.persist( emp );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.delete( emp );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
emp = ( Employer ) s.get( Employee.class, emp.getId() );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertNull( "get did not return null after delete", emp );
}
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( GetLoadTest.class );
}
}

View File

@ -0,0 +1,844 @@
//$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.Iterator;
import java.util.List;
import java.util.Set;
import junit.framework.Test;
import org.hibernate.Hibernate;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.Session;
import org.hibernate.StaleObjectStateException;
import org.hibernate.criterion.Projections;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
/**
* @author Gavin King, Gail Badner (adapted this from "ops" tests version)
*/
public class MergeTest extends AbstractOperationTestCase {
public MergeTest(String str) {
super( str );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( MergeTest.class );
}
public void testMergeStaleVersionFails() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
VersionedEntity entity = new VersionedEntity( "entity", "entity" );
s.persist( entity );
SimpleJtaTransactionManagerImpl.getInstance().commit();
// make the detached 'entity' reference stale...
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
VersionedEntity entity2 = ( VersionedEntity ) s.get( VersionedEntity.class, entity.getId() );
entity2.setName( "entity-name" );
SimpleJtaTransactionManagerImpl.getInstance().commit();
// now try to reattch it
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
try {
s.merge( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
entity = ( VersionedEntity ) getOldToNewEntityRefMap().get( entity );
SimpleJtaTransactionManagerImpl.getInstance().commit();
fail( "was expecting staleness error" );
}
catch ( StaleObjectStateException expected ) {
// expected outcome...
}
finally {
SimpleJtaTransactionManagerImpl.getInstance().rollback();
}
}
public void testMergeBidiPrimayKeyOneToOne() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Person p = new Person( "steve" );
new PersonalDetails( "I have big feet", p );
s.persist( p );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
p.getDetails().setSomePersonalDetail( p.getDetails().getSomePersonalDetail() + " and big hands too" );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
p = ( Person ) s.merge( p );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
p = ( Person ) getOldToNewEntityRefMap().get( p );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 0 );
assertUpdateCount( 1 );
assertDeleteCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.delete( p );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testMergeBidiForeignKeyOneToOne() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Person p = new Person( "steve" );
Address a = new Address( "123 Main", "Austin", "US", p );
s.persist( a );
s.persist( p );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
p.getAddress().setStreetAddress( "321 Main" );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
p = ( Person ) s.merge( p );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 ); // no cascade
assertDeleteCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.delete( a );
s.delete( p );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testNoExtraUpdatesOnMerge() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node node = new Node( "test" );
s.persist( node );
SimpleJtaTransactionManagerImpl.getInstance().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...
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
node = ( Node ) s.merge( node );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().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" );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
node = ( Node ) s.merge( node );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 1 );
assertInsertCount( 0 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
public void testNoExtraUpdatesOnMergeWithCollection() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node parent = new Node( "parent" );
Node child = new Node( "child" );
parent.getChildren().add( child );
child.setParent( parent );
s.persist( parent );
SimpleJtaTransactionManagerImpl.getInstance().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...
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
parent = ( Node ) s.merge( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().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" ) );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
parent = ( Node ) s.merge( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 1 );
assertInsertCount( 1 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
public void testNoExtraUpdatesOnMergeVersioned() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
VersionedEntity entity = new VersionedEntity( "entity", "entity" );
s.persist( entity );
SimpleJtaTransactionManagerImpl.getInstance().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...
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
VersionedEntity mergedEntity = ( VersionedEntity ) s.merge( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
mergedEntity = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedEntity );
SimpleJtaTransactionManagerImpl.getInstance().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" );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
entity = ( VersionedEntity ) s.merge( entity );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 1 );
assertInsertCount( 0 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
public void testNoExtraUpdatesOnMergeVersionedWithCollection() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().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...
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
VersionedEntity mergedParent = ( VersionedEntity ) s.merge( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
mergedParent = ( VersionedEntity ) getOldToNewEntityRefMap().get( mergedParent );
SimpleJtaTransactionManagerImpl.getInstance().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" ) );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
parent = ( VersionedEntity ) s.merge( mergedParent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
parent = ( VersionedEntity ) getOldToNewEntityRefMap().get( parent );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 1 );
assertInsertCount( 1 );
///////////////////////////////////////////////////////////////////////
cleanup();
}
public void testNoExtraUpdatesOnPersistentMergeVersionedWithCollection() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().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...
SimpleJtaTransactionManagerImpl.getInstance().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
VersionedEntity persistentChild = ( VersionedEntity ) 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 );
SimpleJtaTransactionManagerImpl.getInstance().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...
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertUpdateCount( 1 );
assertInsertCount( 1 );
///////////////////////////////////////////////////////////////////////
// cleanup();
}
public void testPersistThenMergeInSameTxnWithVersion() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().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
}
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
public void testPersistThenMergeInSameTxnWithTimestamp() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().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
}
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
public void testMergeDeepTree() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 3 );
assertUpdateCount( 0 );
clearCounts();
grandchild.setDescription( "the grand child" );
Node grandchild2 = new Node( "grandchild2" );
child.addChild( grandchild2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 1 );
clearCounts();
Node child2 = new Node( "child2" );
Node grandchild3 = new Node( "grandchild3" );
child2.addChild( grandchild3 );
root.addChild( child2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.delete( grandchild );
s.delete( grandchild2 );
s.delete( grandchild3 );
s.delete( child );
s.delete( child2 );
s.delete( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testMergeDeepTreeWithGeneratedId() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
root = ( NumberedNode ) s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 1 );
clearCounts();
getSessions().evict( NumberedNode.class );
NumberedNode child2 = new NumberedNode( "child2" );
NumberedNode grandchild3 = new NumberedNode( "grandchild3" );
child2.addChild( grandchild3 );
root.addChild( child2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
root = ( NumberedNode ) s.merge( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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();
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testMergeTree() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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();
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
clearCounts();
root.setDescription( "The root node" );
child.setDescription( "The child node" );
Node secondChild = new Node( "second child" );
root.addChild( secondChild );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.merge( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 2 );
cleanup();
}
public void testMergeTreeWithGeneratedId() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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();
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
clearCounts();
root.setDescription( "The root node" );
child.setDescription( "The child node" );
NumberedNode secondChild = new NumberedNode( "second child" );
root.addChild( secondChild );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.merge( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 2 );
cleanup();
}
public void testMergeManaged() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
s.persist( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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();
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 0 );
assertEquals( root.getChildren().size(), 1 );
assertTrue( root.getChildren().contains( mergedChild ) );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
assertEquals(
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
);
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
public void testMergeManagedUninitializedCollection() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
root.addChild( new NumberedNode( "child" ) );
s.persist( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
NumberedNode newRoot = new NumberedNode( "root" );
newRoot.setId( root.getId() );
SimpleJtaTransactionManagerImpl.getInstance().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 ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 );
assertDeleteCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
assertEquals(
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
);
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
public void testMergeManagedInitializedCollection() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
root.addChild( new NumberedNode( "child" ) );
s.persist( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
NumberedNode newRoot = new NumberedNode( "root" );
newRoot.setId( root.getId() );
SimpleJtaTransactionManagerImpl.getInstance().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 ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 );
assertDeleteCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
assertEquals(
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
);
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
public void testRecursiveMergeTransient() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().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() );
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
public void testDeleteAndMerge() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Employer jboss = new Employer();
s.persist( jboss );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
Employer otherJboss;
otherJboss = ( Employer ) s.get( Employer.class, jboss.getId() );
s.delete( otherJboss );
SimpleJtaTransactionManagerImpl.getInstance().commit();
jboss.setVers( new Integer( 1 ) );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.merge( jboss );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
public void testMergeManyToManyWithCollectionDeference() throws Exception {
// setup base data...
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().commit();
// the competition graph is now detached:
// 1) create a new List reference to represent the competitors
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertFalse( competition == competition2 );
assertFalse( competition2 == competition2copy );
assertFalse( competition.getCompetitors() == competition2.getCompetitors() );
assertEquals( 2, competition2.getCompetitors().size() );
assertEquals( 2, competition2copy.getCompetitors().size() );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
competition = ( Competition ) s.get( Competition.class, competition.getId() );
assertEquals( 2, competition.getCompetitors().size() );
s.delete( competition );
SimpleJtaTransactionManagerImpl.getInstance().commit();
cleanup();
}
private void cleanup() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().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();
Iterator itr = s.createQuery( "from Employer" ).list().iterator();
while ( itr.hasNext() ) {
final Employer employer = ( Employer ) itr.next();
s.delete( employer );
}
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
}

View File

@ -0,0 +1,51 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
-->
<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
<class name="Node" polymorphism="explicit">
<id name="name">
<generator class="assigned"/>
</id>
<property name="description"/>
<many-to-one name="parent"/>
<property name="created" not-null="true"/>
<set name="children"
inverse="true"
cascade="persist,merge,save-update,evict">
<key column="parent"/>
<one-to-many class="Node"/>
</set>
<set name="cascadingChildren" inverse="false" cascade="persist,merge,save-update,evict,delete">
<key column="CASC_PARENT"/>
<one-to-many class="Node"/>
</set>
</class>
<class name="NumberedNode" polymorphism="explicit">
<id name="id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="name">
<column name="name" index="iname" not-null="true"/>
</property>
<property name="description"/>
<property name="created" not-null="true"
type="imm_date"/>
<many-to-one name="parent" class="NumberedNode"/>
<set name="children"
inverse="true"
cascade="persist,merge,save-update">
<key column="parent"/>
<one-to-many class="NumberedNode"/>
</set>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,89 @@
//$Id: Node.java 10759 2006-11-08 00:00:53Z steve.ebersole@jboss.com $
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
import java.sql.Date;
import java.util.HashSet;
import java.util.Set;
/**
* @author Gavin King, Gail Badner (adapted this from "ops" tests version)
*/
public class Node implements Serializable {
private String name;
private String description;
private Date created;
private Node parent;
private Set children = new HashSet();
private Set cascadingChildren = new HashSet();
public Node() {
}
public Node(String name) {
this.name = name;
created = generateCurrentDate();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public Set getChildren() {
return children;
}
public void setChildren(Set children) {
this.children = children;
}
public Node addChild(Node child) {
children.add( child );
child.setParent( this );
return this;
}
public Set getCascadingChildren() {
return cascadingChildren;
}
public void setCascadingChildren(Set cascadingChildren) {
this.cascadingChildren = cascadingChildren;
}
private Date generateCurrentDate() {
// Note : done as java.sql.Date mainly to work around issue with
// MySQL and its lack of milli-second precision on its DATETIME
// and TIMESTAMP datatypes.
return new Date( new java.util.Date().getTime() );
}
}

View File

@ -0,0 +1,83 @@
//$Id: NumberedNode.java 7236 2005-06-20 03:19:34Z oneovthafew $
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
/**
* @author Gavin King, Gail Badner (adapted this from "ops" tests version)
*/
public class NumberedNode implements Serializable {
private long id;
private String name;
private NumberedNode parent;
private Set children = new HashSet();
private String description;
private Date created;
public NumberedNode() {
super();
}
public NumberedNode(String name) {
this.name = name;
created = new Date();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Set getChildren() {
return children;
}
public void setChildren(Set children) {
this.children = children;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public NumberedNode getParent() {
return parent;
}
public void setParent(NumberedNode parent) {
this.parent = parent;
}
public NumberedNode addChild(NumberedNode child) {
children.add( child );
child.setParent( this );
return this;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mappings demonstrating bidirectional one-to-one mappings for testing
with various operations.
Person -> Address is modeled as a bidirectional one to one based on FK.
Person -> Details is modeled as a bidirectional one to one based on PK.
-->
<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
<class name="Person" table="OPS_PERSON">
<id name="id" column="ID" type="long">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string"/>
<one-to-one name="address" class="Address" property-ref="resident"/>
<one-to-one name="details" class="PersonalDetails" cascade="all"/>
</class>
<class name="Address" table="OPS_ADDRESS">
<id name="id" column="ID" type="long">
<generator class="increment"/>
</id>
<property name="streetAddress" column="STREET" type="string"/>
<property name="city" column="CITY" type="string"/>
<property name="country" column="CTRY" type="string"/>
<many-to-one name="resident" column="RESIDENT" class="Person"/>
</class>
<class name="PersonalDetails" table="OPS_PERS_DETAIL">
<id name="id" column="ID" type="long">
<generator class="increment"/>
</id>
<property name="somePersonalDetail" column="SOME_DETAIL" type="string"/>
<one-to-one name="person" class="Person" cascade="none" constrained="true"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
-->
<hibernate-mapping package="org.hibernate.test.nonflushedchanges">
<class name="VersionedEntity" table="V_ENTITY">
<id name="id" column="ID" type="string">
<generator class="assigned"/>
</id>
<version name="version" column="VERS" type="long"/>
<property name="name" column="NAME" type="string"/>
<many-to-one name="parent" class="VersionedEntity"/>
<set name="children"
inverse="true"
cascade="persist,merge,save-update,evict,delete">
<key column="parent"/>
<one-to-many class="VersionedEntity"/>
</set>
</class>
<class name="TimestampedEntity" table="T_ENTITY">
<id name="id" column="ID" type="string">
<generator class="assigned"/>
</id>
<timestamp name="timestamp" column="TS"/>
<property name="name" column="NAME" type="string"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,54 @@
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
/**
* {@inheritDoc}
*
* @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
*/
public class Person implements Serializable {
private Long id;
private String name;
private Address address;
private PersonalDetails details;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public PersonalDetails getDetails() {
return details;
}
public void setDetails(PersonalDetails details) {
this.details = details;
}
}

View File

@ -0,0 +1,47 @@
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
/**
* {@inheritDoc}
*
* @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
*/
public class PersonalDetails implements Serializable {
private Long id;
private String somePersonalDetail;
private Person person;
public PersonalDetails() {
}
public PersonalDetails(String somePersonalDetail, Person person) {
this.somePersonalDetail = somePersonalDetail;
this.person = person;
person.setDetails( this );
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSomePersonalDetail() {
return somePersonalDetail;
}
public void setSomePersonalDetail(String somePersonalDetail) {
this.somePersonalDetail = somePersonalDetail;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}

View File

@ -0,0 +1,492 @@
//$Id: SaveOrUpdateTest.java 10977 2006-12-12 23:28:04Z steve.ebersole@jboss.com $
package org.hibernate.test.nonflushedchanges;
import junit.framework.Test;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Projections;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.test.tm.SimpleJtaTransactionManagerImpl;
/**
* @author Gavin King, Gail Badner (adapted this from "ops" tests version)
*/
public class SaveOrUpdateTest extends AbstractOperationTestCase {
public SaveOrUpdateTest(String str) {
super( str );
}
public void testSaveOrUpdateDeepTree() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
child = ( Node ) getOldToNewEntityRefMap().get( child );
grandchild = ( Node ) getOldToNewEntityRefMap().get( grandchild );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 3 );
assertUpdateCount( 0 );
clearCounts();
grandchild.setDescription( "the grand child" );
Node grandchild2 = new Node( "grandchild2" );
child.addChild( grandchild2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 1 );
clearCounts();
Node child2 = new Node( "child2" );
Node grandchild3 = new Node( "grandchild3" );
child2.addChild( grandchild3 );
root.addChild( child2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
assertUpdateCount( 0 );
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.delete( grandchild );
s.delete( grandchild2 );
s.delete( grandchild3 );
s.delete( child );
s.delete( child2 );
s.delete( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testSaveOrUpdateDeepTreeWithGeneratedId() throws Exception {
boolean instrumented = FieldInterceptionHelper.isInstrumented( new NumberedNode() );
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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 );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
grandchild = ( NumberedNode ) getOldToNewEntityRefMap().get( grandchild );
SimpleJtaTransactionManagerImpl.getInstance().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 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( instrumented ? 1 : 3 );
clearCounts();
NumberedNode child2 = new NumberedNode( "child2" );
NumberedNode grandchild3 = new NumberedNode( "grandchild3" );
child2.addChild( grandchild3 );
root.addChild( child2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
assertUpdateCount( instrumented ? 0 : 4 );
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().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();
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testSaveOrUpdateTree() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node root = new Node( "root" );
Node child = new Node( "child" );
root.addChild( child );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
child = ( Node ) getOldToNewEntityRefMap().get( child );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
clearCounts();
root.setDescription( "The root node" );
child.setDescription( "The child node" );
Node secondChild = new Node( "second child" );
root.addChild( secondChild );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.createQuery( "delete from Node where parent is not null" ).executeUpdate();
s.createQuery( "delete from Node" ).executeUpdate();
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testSaveOrUpdateTreeWithGeneratedId() throws Exception {
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
NumberedNode child = new NumberedNode( "child" );
root.addChild( child );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 2 );
clearCounts();
root.setDescription( "The root node" );
child.setDescription( "The child node" );
NumberedNode secondChild = new NumberedNode( "second child" );
root.addChild( secondChild );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 2 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.createQuery( "delete from NumberedNode where parent is not null" ).executeUpdate();
s.createQuery( "delete from NumberedNode" ).executeUpdate();
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testSaveOrUpdateManaged() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
NumberedNode child = new NumberedNode( "child" );
root.addChild( child );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
assertNull( getOldToNewEntityRefMap().get( child ) );
s.flush();
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
child = ( NumberedNode ) root.getChildren().iterator().next();
assertTrue( s.contains( child ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
child = ( NumberedNode ) getOldToNewEntityRefMap().get( child );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertTrue( root.getChildren().contains( child ) );
assertEquals( root.getChildren().size(), 1 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
assertEquals(
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
);
s.delete( root );
s.delete( child );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testSaveOrUpdateGot() throws Exception {
boolean instrumented = FieldInterceptionHelper.isInstrumented( new NumberedNode() );
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
NumberedNode root = new NumberedNode( "root" );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 0 );
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 0 );
assertUpdateCount( instrumented ? 0 : 1 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
root = ( NumberedNode ) s.get( NumberedNode.class, new Long( root.getId() ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
Hibernate.initialize( root.getChildren() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
NumberedNode child = new NumberedNode( "child" );
root.addChild( child );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( NumberedNode ) getOldToNewEntityRefMap().get( root );
assertTrue( Hibernate.isInitialized( root.getChildren() ) );
child = ( NumberedNode ) root.getChildren().iterator().next();
assertTrue( s.contains( child ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( instrumented ? 0 : 1 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
assertEquals(
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
);
s.delete( root );
s.delete( child );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testSaveOrUpdateGotWithMutableProp() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node root = new Node( "root" );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
assertUpdateCount( 0 );
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 0 );
assertUpdateCount( 0 );
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
root = ( Node ) s.get( Node.class, "root" );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
Hibernate.initialize( root.getChildren() );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
SimpleJtaTransactionManagerImpl.getInstance().commit();
clearCounts();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
Node child = new Node( "child" );
root.addChild( child );
s.saveOrUpdate( root );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
child = ( Node ) root.getChildren().iterator().next();
assertTrue( s.contains( child ) );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
root = ( Node ) getOldToNewEntityRefMap().get( root );
child = ( Node ) getOldToNewEntityRefMap().get( child );
SimpleJtaTransactionManagerImpl.getInstance().commit();
assertInsertCount( 1 );
//assertUpdateCount( 1 ); //note: will fail here if no second-level cache
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
assertEquals(
s.createCriteria( Node.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
);
s.delete( root );
s.delete( child );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void testEvictThenSaveOrUpdate() throws Exception {
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s = openSession();
Node parent = new Node( "1:parent" );
Node child = new Node( "2:child" );
Node grandchild = new Node( "3:grandchild" );
parent.addChild( child );
child.addChild( grandchild );
s.saveOrUpdate( parent );
s = applyNonFlushedChangesToNewSessionCloseOldSession( s );
SimpleJtaTransactionManagerImpl.getInstance().commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s1 = openSession();
child = ( Node ) s1.load( Node.class, "2:child" );
s1 = applyNonFlushedChangesToNewSessionCloseOldSession( s1 );
child = ( Node ) getOldToNewEntityRefMap().get( child );
assertTrue( s1.contains( child ) );
assertFalse( Hibernate.isInitialized( child ) );
assertTrue( s1.contains( child.getParent() ) );
assertTrue( Hibernate.isInitialized( child ) );
assertFalse( Hibernate.isInitialized( child.getChildren() ) );
assertFalse( Hibernate.isInitialized( child.getParent() ) );
assertTrue( s1.contains( child ) );
s1 = applyNonFlushedChangesToNewSessionCloseOldSession( s1 );
// child is an initialized proxy; after serialization, it is
// the proxy is replaced by its implementation
// TODO: find out if this is how this should work...
child = ( Node ) getOldToNewEntityRefMap().get(
( ( HibernateProxy ) child ).getHibernateLazyInitializer().getImplementation()
);
s1.evict( child );
assertFalse( s1.contains( child ) );
assertTrue( s1.contains( child.getParent() ) );
javax.transaction.Transaction tx1 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
SimpleJtaTransactionManagerImpl.getInstance().begin();
Session s2 = openSession();
s2.saveOrUpdate( child );
s2 = applyNonFlushedChangesToNewSessionCloseOldSession( s2 );
child = ( Node ) getOldToNewEntityRefMap().get( child );
assertTrue( s2.contains( child ) );
assertFalse( s1.contains( child ) );
assertTrue( s2.contains( child.getParent() ) );
assertFalse( s1.contains( child.getParent() ) );
assertFalse( Hibernate.isInitialized( child.getChildren() ) );
assertFalse( Hibernate.isInitialized( child.getParent() ) );
assertEquals( 1, child.getChildren().size() );
assertEquals( "1:parent", child.getParent().getName() );
assertTrue( Hibernate.isInitialized( child.getChildren() ) );
assertFalse( Hibernate.isInitialized( child.getParent() ) );
assertNull( child.getParent().getDescription() );
assertTrue( Hibernate.isInitialized( child.getParent() ) );
s1 = applyNonFlushedChangesToNewSessionCloseOldSession( s1 );
s2 = applyNonFlushedChangesToNewSessionCloseOldSession( s2 );
javax.transaction.Transaction tx2 = SimpleJtaTransactionManagerImpl.getInstance().suspend();
SimpleJtaTransactionManagerImpl.getInstance().resume( tx1 );
tx1.commit();
SimpleJtaTransactionManagerImpl.getInstance().resume( tx2 );
tx2.commit();
SimpleJtaTransactionManagerImpl.getInstance().begin();
s = openSession();
s.delete( s.get( Node.class, "3:grandchild" ) );
s.delete( s.get( Node.class, "2:child" ) );
s.delete( s.get( Node.class, "1:parent" ) );
SimpleJtaTransactionManagerImpl.getInstance().commit();
}
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
}
public String[] getMappings() {
return new String[] { "nonflushedchanges/Node.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( SaveOrUpdateTest.class );
}
}

View File

@ -0,0 +1,48 @@
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
import java.util.Date;
/**
* todo: describe TimestampedEntity
*
* @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
*/
public class TimestampedEntity implements Serializable {
private String id;
private String name;
private Date timestamp;
public TimestampedEntity() {
}
public TimestampedEntity(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
}

View File

@ -0,0 +1,67 @@
package org.hibernate.test.nonflushedchanges;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* VersionedEntity
*
* @author Steve Ebersole, Gail Badner (adapted this from "ops" tests version)
*/
public class VersionedEntity implements Serializable {
private String id;
private String name;
private long version;
private VersionedEntity parent;
private Set children = new HashSet();
public VersionedEntity() {
}
public VersionedEntity(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public VersionedEntity getParent() {
return parent;
}
public void setParent(VersionedEntity parent) {
this.parent = parent;
}
public Set getChildren() {
return children;
}
public void setChildren(Set children) {
this.children = children;
}
}