Author: gbadner
Date: 2010-02-24 16:20:26 -0500 (Wed, 24 Feb 2010)
New Revision: 18873
Modified:
core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java
Log:
HHH-4809 : Immutable entities added to a session have Status.MANAGED unless loaded by the
Session
Modified: core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java 2010-02-24
20:21:08 UTC (rev 18872)
+++ core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -309,6 +309,9 @@
loadedState = null;
}
else {
+ if ( ! persister.isMutable() ) {
+ throw new IllegalStateException( "Cannot make an immutable entity
modifiable." );
+ }
setStatus( Status.MANAGED );
loadedState = getPersister().getPropertyValues( entity, entityMode );
}
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -88,7 +88,7 @@
EntityEntry newEntry = source.getPersistenceContext().addEntity(
object,
- Status.MANAGED,
+ ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
values,
key,
version,
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -333,7 +333,7 @@
Object version = Versioning.getVersion( values, persister );
source.getPersistenceContext().addEntity(
entity,
- Status.MANAGED,
+ ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
values,
key,
version,
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -126,7 +126,7 @@
entityEntry = persistenceContext.addEntity(
entity,
- Status.MANAGED,
+ ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
persister.getPropertyValues( entity, source.getEntityMode() ),
key,
version,
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -194,7 +194,7 @@
source.getPersistenceContext().addEntity(
entity,
- Status.MANAGED,
+ ( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
null,
new EntityKey( id, persister, source.getEntityMode() ),
version,
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Contract.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -124,9 +124,4 @@
public void setInfos(Set infos) {
this.infos = infos;
}
-
- public void addInfo(Info info) {
- infos.add( info );
- info.setContract( this );
- }
}
Modified:
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.hbm.xml 2010-02-24
21:20:26 UTC (rev 18873)
@@ -15,7 +15,6 @@
<generator class="increment"/>
</id>
<property name="text"/>
- <many-to-one name="contract" not-null="false"/>
</class>
<class name="Plan" mutable="false">
@@ -27,6 +26,10 @@
<key column="plan"/>
<many-to-many column="contract" class="Contract"/>
</set>
+ <set name="infos" inverse="false"
mutable="true" cascade="all-delete-orphan">
+ <key column="plan"/>
+ <one-to-many class="Info"/>
+ </set>
</class>
<class name="Party" mutable="false">
@@ -36,6 +39,10 @@
<!-- <many-to-one name="contract" update="false"
insert="false"/> -->
<many-to-one name="contract" not-null="true"/>
<property name="name" not-null="true"/>
+ <set name="infos" inverse="false"
mutable="true" cascade="all-delete-orphan">
+ <key column="party"/>
+ <one-to-many class="Info"/>
+ </set>
</class>
<class name="Contract" mutable="false">
@@ -64,7 +71,7 @@
<key column="contract"/>
<one-to-many class="Party"/>
</set>
- <set name="infos" inverse="true" mutable="true"
cascade="all" fetch="join">
+ <set name="infos" inverse="false"
mutable="true" cascade="all-delete-orphan">
<key column="contract"/>
<one-to-many class="Info"/>
</set>
@@ -76,6 +83,13 @@
<key-property name="version"/>
</composite-id>
<property name="text" type="text"/>
+ <set name="infos" inverse="false"
mutable="true" cascade="all-delete-orphan">
+ <key>
+ <column name="contract"/>
+ <column name="version"/>
+ </key>
+ <one-to-many class="Info"/>
+ </set>
</class>
</hibernate-mapping>
Modified:
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.java 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ContractVariation.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -2,12 +2,15 @@
package org.hibernate.test.immutable;
import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
public class ContractVariation implements Serializable {
private int version;
private Contract contract;
private String text;
+ private Set infos = new HashSet();
public Contract getContract() {
return contract;
@@ -42,4 +45,12 @@
this.version = version;
contract.getVariations().add(this);
}
+
+ public Set getInfos() {
+ return infos;
+ }
+
+ public void setInfos(Set infos) {
+ this.infos = infos;
+ }
}
Modified:
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java
===================================================================
---
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java 2010-02-24
20:21:08 UTC (rev 18872)
+++
core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/ImmutableTest.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -38,6 +38,7 @@
import org.hibernate.criterion.Projections;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.proxy.HibernateProxy;
/**
* @author Gavin King
@@ -61,6 +62,126 @@
return new FunctionalTestClassTestSuite( ImmutableTest.class );
}
+ public void testChangeImmutableEntityProxyToModifiable() {
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+
+ clearCounts();
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertTrue( s.isReadOnly( c ) );
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
+
+ try {
+ assertTrue( c instanceof HibernateProxy );
+ s.setReadOnly( c, false );
+ }
+ catch (IllegalStateException ex) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ s.close();
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount()
).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection(
Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
+ public void testChangeImmutableEntityToModifiable() {
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+
+ clearCounts();
+
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertTrue( s.isReadOnly( c ) );
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
+
+ try {
+ assertTrue( c instanceof HibernateProxy );
+ s.setReadOnly( ( ( HibernateProxy ) c
).getHibernateLazyInitializer().getImplementation(), false );
+ }
+ catch (IllegalStateException ex) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ s.close();
+ }
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount()
).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection(
Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 3 );
+ }
+
public void testPersistImmutable() {
Contract c = new Contract( null, "gavin", "phone");
ContractVariation cv1 = new ContractVariation(1, c);
@@ -73,10 +194,9 @@
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
- // c, cv1, and cv2 were added to s by s.persist(c) (not hibernate), so they are
modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
t.commit();
s.close();
@@ -87,7 +207,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -96,7 +215,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
s.delete(c);
@@ -121,10 +239,9 @@
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
- // c, cv1, and cv2 were added to s by s.persist(c) (not hibernate), so they are
modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
c.setCustomerName( "gail" );
t.commit();
s.close();
@@ -136,7 +253,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -145,7 +261,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
s.delete(c);
@@ -169,10 +284,9 @@
Session s = openSession();
Transaction t = s.beginTransaction();
s.save(c);
- // c, cv1, and cv2 were added to s by s.persist(c) (not hibernate), so they are
modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
t.commit();
s.close();
@@ -183,7 +297,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -192,7 +305,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
s.delete(c);
@@ -216,10 +328,9 @@
Session s = openSession();
Transaction t = s.beginTransaction();
s.saveOrUpdate(c);
- // c, cv1, and cv2 were added to s by s.persist(c) (not hibernate), so they are
modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
t.commit();
s.close();
@@ -230,7 +341,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -239,7 +349,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
s.delete(c);
@@ -263,10 +372,9 @@
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
- // c, cv1, and cv2 were added to s by s.persist(c) (not hibernate), so they are
modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
t.commit();
s.close();
@@ -277,12 +385,10 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s, so it should be read-only
assertTrue( s.isReadOnly( c ) );
c.setCustomerName("foo bar");
cv1 = (ContractVariation) c.getVariations().iterator().next();
cv1.setText("blah blah");
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertFalse( s.contains( cv2 ) );
t.commit();
@@ -298,7 +404,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -307,7 +412,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
s.delete(c);
@@ -331,10 +435,9 @@
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(c);
- // c, cv1, and cv2 were added to s by s.persist(c) (not hibernate), so they are
modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
c.setCustomerName( "Sherman" );
t.commit();
s.close();
@@ -346,12 +449,10 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s, so it should be read-only
assertTrue( s.isReadOnly( c ) );
c.setCustomerName("foo bar");
cv1 = (ContractVariation) c.getVariations().iterator().next();
cv1.setText("blah blah");
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertFalse( s.contains( cv2 ) );
t.commit();
@@ -367,7 +468,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -376,7 +476,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
s.delete(c);
@@ -410,7 +509,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.createCriteria(Contract.class).uniqueResult();
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -419,7 +517,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
c.setCustomerName( "Sherman" );
@@ -454,7 +551,6 @@
s = openSession();
t = s.beginTransaction();
c = (Contract) s.get( Contract.class, c.getId() );
- // c was loaded into s by hibernate, so it should be read-only
assertTrue( s.isReadOnly( c ) );
assertEquals( c.getCustomerName(), "gavin" );
assertEquals( c.getVariations().size(), 2 );
@@ -463,7 +559,6 @@
assertEquals( cv1.getText(), "expensive" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
- // cv1 and cv2 were loaded into s by hibernate, so they should be read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
c.setCustomerName( "Sherman" );
@@ -559,15 +654,17 @@
t = s.beginTransaction();
c.setCustomerName("foo bar");
s.update( c );
- // c was not loaded into s by hibernate, so it should be modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.contains( cv1 ) );
- assertFalse( s.contains( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ for ( Iterator it = c.getVariations().iterator(); it.hasNext(); ) {
+ assertTrue( s.contains( it.next() ) );
+ }
t.commit();
- // c, cv1, and cv2 were not loaded into s by hibernate, so they are modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ for ( Iterator it = c.getVariations().iterator(); it.hasNext(); ) {
+ ContractVariation cv = ( ContractVariation ) it.next();
+ assertTrue( s.contains( cv ) );
+ assertTrue( s.isReadOnly( cv ) );
+ }
s.close();
assertUpdateCount( 0 );
@@ -615,14 +712,13 @@
cv1 = (ContractVariation) c.getVariations().iterator().next();
cv1.setText("blah blah");
s.update( c );
- // c was not loaded into s by hibernate, so it should be modifiable
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.contains( cv1 ) );
- assertFalse( s.contains( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.contains( cv1 ) );
+ assertTrue( s.contains( cv2 ) );
t.commit();
- assertFalse( s.isReadOnly( c ) );
- assertFalse( s.isReadOnly( cv1 ) );
- assertFalse( s.isReadOnly( cv2 ) );
+ assertTrue( s.isReadOnly( c ) );
+ assertTrue( s.isReadOnly( cv1 ) );
+ assertTrue( s.isReadOnly( cv2 ) );
s.close();
assertUpdateCount( 0 );
@@ -667,8 +763,9 @@
s = openSession();
t = s.beginTransaction();
c.getVariations().add( new ContractVariation(3, c) );
+ s.update( c );
try {
- s.update( c );
+ t.commit();
fail( "should have failed because reassociated object has a dirty
collection");
}
catch ( HibernateException ex ) {
@@ -722,13 +819,11 @@
s = openSession();
t = s.beginTransaction();
c = ( Contract ) s.merge( c );
- // c was loaded into s by hibernate in the merge process, so it is read-only
assertTrue( s.isReadOnly( c ) );
assertTrue( Hibernate.isInitialized( c.getVariations() ) );
Iterator it = c.getVariations().iterator();
cv1 = (ContractVariation) it.next();
cv2 = (ContractVariation) it.next();
- // cv1 and cv2 were loaded into s by hibernate in the merge process, so they are
read-only
assertTrue( s.isReadOnly( cv1 ) );
assertTrue( s.isReadOnly( cv2 ) );
t.commit();
@@ -778,13 +873,11 @@
t = s.beginTransaction();
c.setCustomerName("foo bar");
c = ( Contract ) s.merge( c );
- // c was loaded into s by hibernate in the merge process, so it is read-only
assertTrue( s.isReadOnly( c ) );
assertTrue( Hibernate.isInitialized( c.getVariations() ) );
Iterator it = c.getVariations().iterator();
cv1 = (ContractVariation) it.next();
cv2 = (ContractVariation) it.next();
- // cv1 and cv2 were loaded into s by hibernate in the merge process, so they are
read-only
assertTrue( s.isReadOnly( c ) );
assertTrue( s.isReadOnly( c ) );
t.commit();
@@ -836,13 +929,11 @@
cv1 = (ContractVariation) c.getVariations().iterator().next();
cv1.setText("blah blah");
c = ( Contract ) s.merge( c );
- // c was loaded into s by hibernate in the merge process, so it is read-only
assertTrue( s.isReadOnly( c ) );
assertTrue( Hibernate.isInitialized( c.getVariations() ) );
Iterator it = c.getVariations().iterator();
cv1 = (ContractVariation) it.next();
cv2 = (ContractVariation) it.next();
- // cv1 and cv2 were loaded into s by hibernate in the merge process, so they are
read-only
assertTrue( s.isReadOnly( c ) );
assertTrue( s.isReadOnly( c ) );
t.commit();
@@ -925,6 +1016,212 @@
assertDeleteCount( 3 );
}
+ public void testNewEntityViaImmutableEntityWithImmutableCollectionUsingSaveOrUpdate() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ cv1.getInfos().add( new Info( "cv1 info" ) );
+ s.saveOrUpdate( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ assertEquals( 1, cv1.getInfos().size() );
+ assertEquals( "cv1 info", ( ( Info ) cv1.getInfos().iterator().next()
).getText() );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount()
).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection(
Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 4 );
+ }
+
+ public void testNewEntityViaImmutableEntityWithImmutableCollectionUsingMerge() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ cv1.getInfos().add( new Info( "cv1 info" ) );
+ s.merge( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 1 );
+ assertUpdateCount( 0 );
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ assertEquals( 1, cv1.getInfos().size() );
+ assertEquals( "cv1 info", ( ( Info ) cv1.getInfos().iterator().next()
).getText() );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount()
).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection(
Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 4 );
+ }
+
+ public void
testUpdatedEntityViaImmutableEntityWithImmutableCollectionUsingSaveOrUpdate() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ Info cv1Info = new Info( "cv1 info" );
+ cv1.getInfos().add( cv1Info );
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 4 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ cv1Info.setText( "new cv1 info" );
+ s.saveOrUpdate( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ assertEquals( 1, cv1.getInfos().size() );
+ assertEquals( "new cv1 info", ( ( Info ) cv1.getInfos().iterator().next()
).getText() );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount()
).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection(
Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 4 );
+ }
+
+ public void testUpdatedEntityViaImmutableEntityWithImmutableCollectionUsingMerge() {
+ clearCounts();
+
+ Contract c = new Contract( null, "gavin", "phone");
+ ContractVariation cv1 = new ContractVariation(1, c);
+ cv1.setText("expensive");
+ Info cv1Info = new Info( "cv1 info" );
+ cv1.getInfos().add( cv1Info );
+ ContractVariation cv2 = new ContractVariation(2, c);
+ cv2.setText("more expensive");
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ assertInsertCount( 4 );
+ assertUpdateCount( 0 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ cv1Info.setText( "new cv1 info" );
+ s.merge( c );
+ t.commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 1 );
+ clearCounts();
+
+ s = openSession();
+ t = s.beginTransaction();
+ c = (Contract) s.createCriteria(Contract.class).uniqueResult();
+ assertEquals( c.getCustomerName(), "gavin" );
+ assertEquals( c.getVariations().size(), 2 );
+ Iterator it = c.getVariations().iterator();
+ cv1 = (ContractVariation) it.next();
+ assertEquals( cv1.getText(), "expensive" );
+ assertEquals( 1, cv1.getInfos().size() );
+ assertEquals( "new cv1 info", ( ( Info ) cv1.getInfos().iterator().next()
).getText() );
+ cv2 = (ContractVariation) it.next();
+ assertEquals( cv2.getText(), "more expensive" );
+ s.delete(c);
+ assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount()
).uniqueResult(), new Long(0) );
+ assertEquals( s.createCriteria(ContractVariation.class).setProjection(
Projections.rowCount() ).uniqueResult(), new Long(0) );
+ t.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 4 );
+ }
+
protected void clearCounts() {
getSessions().getStatistics().clear();
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java 2010-02-24
20:21:08 UTC (rev 18872)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Info.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -7,7 +7,6 @@
private long id;
private String text;
- private Contract contract;
public Info() {
super();
@@ -32,12 +31,4 @@
public void setId(long id) {
this.id = id;
}
-
- public Contract getContract() {
- return contract;
- }
-
- public void setContract(Contract contract ) {
- this.contract = contract;
- }
}
\ No newline at end of file
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java 2010-02-24
20:21:08 UTC (rev 18872)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Party.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -12,6 +12,7 @@
private long id;
private Contract contract;
private String name;
+ private Set infos = new HashSet();
public Party() {
super();
@@ -44,4 +45,12 @@
public void setContract(Contract contract) {
this.contract = contract;
}
+
+ public Set getInfos() {
+ return infos;
+ }
+
+ public void setInfos(Set infos) {
+ this.infos = infos;
+ }
}
\ No newline at end of file
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java 2010-02-24
20:21:08 UTC (rev 18872)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/immutable/Plan.java 2010-02-24
21:20:26 UTC (rev 18873)
@@ -11,6 +11,7 @@
private long id;
private String description;
private Set contracts;
+ private Set infos;
public Plan() {
this( null );
@@ -19,6 +20,7 @@
public Plan(String description) {
this.description = description;
contracts = new HashSet();
+ infos = new HashSet();
}
public long getId() {
@@ -77,4 +79,12 @@
contracts.remove( sub );
}
}
+
+ public Set getInfos() {
+ return infos;
+ }
+
+ public void setInfos(Set infos) {
+ this.infos = infos;
+ }
}
\ No newline at end of file