Skip to content

Commit

Permalink
HHH-3662 : Merging read-only entities causes AssertionError
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.jboss.org/repos/hibernate/core/branches/Branch_3_2@16513 1b8cb986-b30d-0410-93ca-fae66ebed9b2
  • Loading branch information
gbadner committed May 6, 2009
1 parent 746fcef commit 53c075e
Show file tree
Hide file tree
Showing 7 changed files with 951 additions and 4 deletions.
28 changes: 26 additions & 2 deletions src/org/hibernate/event/def/DefaultMergeEventListener.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
//$Id$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.event.def;

import java.io.Serializable;
Expand Down Expand Up @@ -70,8 +94,8 @@ public void onMerge(MergeEvent event) throws HibernateException {
// TODO: cache the entity name somewhere so that it is available to this exception
// entity name will not be available for non-POJO entities
}
if ( entry.getStatus() != Status.MANAGED ) {
throw new AssertionFailure( "Merged entity does not have status set to MANAGED; "+entry+" status="+entry.getStatus() );
if ( entry.getStatus() != Status.MANAGED && entry.getStatus() != Status.READ_ONLY ) {
throw new AssertionFailure( "Merged entity does not have status set to MANAGED or READ_ONLY; "+entry+" status="+entry.getStatus() );
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion test/org/hibernate/test/AllTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
import org.hibernate.test.proxy.ProxyTest;
import org.hibernate.test.querycache.QueryCacheTest;
import org.hibernate.test.readonly.ReadOnlyTest;
import org.hibernate.test.readonly.ReadOnlyVersionedNodesTest;
import org.hibernate.test.reattachment.CollectionReattachmentTest;
import org.hibernate.test.reattachment.ProxyReattachmentTest;
import org.hibernate.test.rowid.RowIdTest;
Expand Down Expand Up @@ -304,6 +305,7 @@ public static Test unfilteredSuite() {
suite.addTest( EmbeddedCompositeIdTest.suite() );
suite.addTest( ImmutableTest.suite() );
suite.addTest( ReadOnlyTest.suite() );
suite.addTest( ReadOnlyVersionedNodesTest.suite() );
suite.addTest( IdClassTest.suite() );
suite.addTest( ArrayTest.suite() );
suite.addTest( TernaryTest.suite() );
Expand Down Expand Up @@ -633,4 +635,4 @@ private TestSuite instantiateCopy(TestSuite suite) {
}
}
}
}
}
265 changes: 264 additions & 1 deletion test/org/hibernate/test/immutable/ImmutableTest.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,37 @@
//$Id$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.test.immutable;

import java.util.Iterator;

import junit.framework.Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Projections;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
Expand Down Expand Up @@ -53,14 +80,250 @@ public void testImmutable() {
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" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
s.delete(c);
assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
t.commit();
s.close();
}

public void testImmutableParentEntityWithUpdate() {
Contract c = new Contract("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();

s = openSession();
t = s.beginTransaction();
c.setCustomerName("foo bar");
s.update( c );
t.commit();
s.close();

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" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
s.delete(c);
assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
t.commit();
s.close();
}

public void testImmutableChildEntityWithUpdate() {
Contract c = new Contract("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();

s = openSession();
t = s.beginTransaction();
cv1 = (ContractVariation) c.getVariations().iterator().next();
cv1.setText("blah blah");
s.update( c );
t.commit();
s.close();

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" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
s.delete(c);
assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
t.commit();
s.close();
}

}
public void testImmutableCollectionWithUpdate() {
Contract c = new Contract("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();

s = openSession();
t = s.beginTransaction();
c.getVariations().add( new ContractVariation(3, c) );
try {
s.update( c );
fail( "should have failed because reassociated object has a dirty collection");
}
catch ( HibernateException ex ) {
// expected
}
finally {
t.rollback();
s.close();
}

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" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
s.delete(c);
assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
t.commit();
s.close();
}

public void testImmutableParentEntityWithMerge() {
Contract c = new Contract("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();

s = openSession();
t = s.beginTransaction();
c.setCustomerName("foo bar");
s.merge( c );
t.commit();
s.close();

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" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
s.delete(c);
assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
t.commit();
s.close();
}

public void testImmutableChildEntityWithMerge() {
Contract c = new Contract("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();

s = openSession();
t = s.beginTransaction();
cv1 = (ContractVariation) c.getVariations().iterator().next();
cv1.setText("blah blah");
s.merge( c );
t.commit();
s.close();

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" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
s.delete(c);
assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
t.commit();
s.close();
}

public void testImmutableCollectionWithMerge() {
Contract c = new Contract("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();

s = openSession();
t = s.beginTransaction();
c.getVariations().add( new ContractVariation(3, c) );
s.merge( c );
try {
t.commit();
fail( "should have failed because an immutable collection was changed");
}
catch ( HibernateException ex ) {
// expected
t.rollback();
}
finally {
s.close();
}

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" );
cv2 = (ContractVariation) it.next();
assertEquals( cv2.getText(), "more expensive" );
s.delete(c);
assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) );
t.commit();
s.close();
}
}
Loading

0 comments on commit 53c075e

Please sign in to comment.