Author: gbadner
Date: 2009-11-17 18:17:25 -0500 (Tue, 17 Nov 2009)
New Revision: 17998
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java
Log:
HHH-2762 : new unit tests for
SessionImplementor.getNonFlushedChanges()/applyNonFlushedChanges() implementation
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/AbstractOperationTestCase.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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 );
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Address.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.hbm.xml 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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>
+
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competition.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Competitor.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/CreateTest.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -0,0 +1,250 @@
+//$Id: CreateTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)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();
+ }
+}
\ No newline at end of file
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/DeleteTest.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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 );
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employee.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.hbm.xml 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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>
+
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Employer.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -0,0 +1,126 @@
+//$Id: GetLoadTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)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 );
+ }
+}
+
Property changes on:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/GetLoadTest.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -0,0 +1,844 @@
+//$Id: MergeTest.java 11037 2007-01-09 16:04:16Z steve.ebersole(a)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();
+ }
+}
+
Property changes on:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/MergeTest.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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>
+
Property changes on:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.hbm.xml
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -0,0 +1,89 @@
+//$Id: Node.java 10759 2006-11-08 00:00:53Z steve.ebersole(a)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() );
+ }
+}
Property changes on:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Node.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Property changes on:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/NumberedNode.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OneToOne.hbm.xml 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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>
\ No newline at end of file
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/OptLockEntity.hbm.xml 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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>
+
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/Person.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/PersonalDetails.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -0,0 +1,492 @@
+//$Id: SaveOrUpdateTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)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 );
+ }
+
+}
+
Property changes on:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/SaveOrUpdateTest.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/TimestampedEntity.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}
+
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java
(rev 0)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/nonflushedchanges/VersionedEntity.java 2009-11-17
23:17:25 UTC (rev 17998)
@@ -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;
+ }
+}