HHH-4809 : Immutable entities added to a session have Status.MANAGED unless loaded by the Session

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18873 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2010-02-24 21:20:26 +00:00
parent d26e4f1cad
commit 3df8bc5712
12 changed files with 416 additions and 86 deletions

View File

@ -309,6 +309,9 @@ public final class EntityEntry implements Serializable {
loadedState = null;
}
else {
if ( ! persister.isMutable() ) {
throw new IllegalStateException( "Cannot make an immutable entity modifiable." );
}
setStatus( Status.MANAGED );
loadedState = getPersister().getPropertyValues( entity, entityMode );
}

View File

@ -88,7 +88,7 @@ public class AbstractReassociateEventListener implements Serializable {
EntityEntry newEntry = source.getPersistenceContext().addEntity(
object,
Status.MANAGED,
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
values,
key,
version,

View File

@ -333,7 +333,7 @@ public abstract class AbstractSaveEventListener extends AbstractReassociateEvent
Object version = Versioning.getVersion( values, persister );
source.getPersistenceContext().addEntity(
entity,
Status.MANAGED,
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
values,
key,
version,

View File

@ -126,7 +126,7 @@ public class DefaultDeleteEventListener implements DeleteEventListener {
entityEntry = persistenceContext.addEntity(
entity,
Status.MANAGED,
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
persister.getPropertyValues( entity, source.getEntityMode() ),
key,
version,

View File

@ -194,7 +194,7 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
source.getPersistenceContext().addEntity(
entity,
Status.MANAGED,
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
null,
new EntityKey( id, persister, source.getEntityMode() ),
version,

View File

@ -124,9 +124,4 @@ public class Contract implements Serializable {
public void setInfos(Set infos) {
this.infos = infos;
}
public void addInfo(Info info) {
infos.add( info );
info.setContract( this );
}
}

View File

@ -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>

View File

@ -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 @@ public class ContractVariation implements Serializable {
this.version = version;
contract.getVariations().add(this);
}
public Set getInfos() {
return infos;
}
public void setInfos(Set infos) {
this.infos = infos;
}
}

View File

@ -38,6 +38,7 @@ import org.hibernate.cfg.Environment;
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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 @@ public class ImmutableTest extends FunctionalTestCase {
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();
}

View File

@ -7,7 +7,6 @@ public class Info implements Serializable {
private long id;
private String text;
private Contract contract;
public Info() {
super();
@ -32,12 +31,4 @@ public class Info implements Serializable {
public void setId(long id) {
this.id = id;
}
public Contract getContract() {
return contract;
}
public void setContract(Contract contract ) {
this.contract = contract;
}
}

View File

@ -12,6 +12,7 @@ public class Party implements Serializable {
private long id;
private Contract contract;
private String name;
private Set infos = new HashSet();
public Party() {
super();
@ -44,4 +45,12 @@ public class Party implements Serializable {
public void setContract(Contract contract) {
this.contract = contract;
}
public Set getInfos() {
return infos;
}
public void setInfos(Set infos) {
this.infos = infos;
}
}

View File

@ -11,6 +11,7 @@ public class Plan implements Serializable {
private long id;
private String description;
private Set contracts;
private Set infos;
public Plan() {
this( null );
@ -19,6 +20,7 @@ public class Plan implements Serializable {
public Plan(String description) {
this.description = description;
contracts = new HashSet();
infos = new HashSet();
}
public long getId() {
@ -77,4 +79,12 @@ public class Plan implements Serializable {
contracts.remove( sub );
}
}
public Set getInfos() {
return infos;
}
public void setInfos(Set infos) {
this.infos = infos;
}
}