Author: steve.ebersole(a)jboss.com
Date: 2007-01-09 11:04:16 -0500 (Tue, 09 Jan 2007)
New Revision: 11037
Modified:
trunk/Hibernate3/src/org/hibernate/type/CollectionType.java
trunk/Hibernate3/test/org/hibernate/test/ops/Competition.hbm.xml
trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
Log:
HHH-2292 : merge() : detached + bare collections
Modified: trunk/Hibernate3/src/org/hibernate/type/CollectionType.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/type/CollectionType.java 2007-01-09 16:03:50 UTC
(rev 11036)
+++ trunk/Hibernate3/src/org/hibernate/type/CollectionType.java 2007-01-09 16:04:16 UTC
(rev 11037)
@@ -414,8 +414,6 @@
SessionImplementor session) {
// TODO: does not work for EntityMode.DOM4J yet!
java.util.Collection result = ( java.util.Collection ) target;
- final boolean isPC = ( result instanceof PersistentCollection );
- final boolean wasOriginalDirty = ( original instanceof PersistentCollection &&
( ( PersistentCollection ) original ).isDirty() );
result.clear();
// copy elements into newly empty target collection
@@ -425,8 +423,19 @@
result.add( elemType.replace( iter.next(), null, session, owner, copyCache ) );
}
- if ( result instanceof PersistentCollection && !wasOriginalDirty ) {
- ( ( PersistentCollection ) result ).clearDirty();
+ // if the original is a PersistentCollection, and that original
+ // was not flagged as dirty, then reset the target's dirty flag
+ // here after the copy operation.
+ // </p>
+ // One thing to be careful of here is a "bare" original collection
+ // in which case we should never ever ever reset the dirty flag
+ // on the target because we simply do not know...
+ if ( original instanceof PersistentCollection ) {
+ if ( result instanceof PersistentCollection ) {
+ if ( ! ( ( PersistentCollection ) original ).isDirty() ) {
+ ( ( PersistentCollection ) result ).clearDirty();
+ }
+ }
}
return result;
Modified: trunk/Hibernate3/test/org/hibernate/test/ops/Competition.hbm.xml
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/ops/Competition.hbm.xml 2007-01-09 16:03:50
UTC (rev 11036)
+++ trunk/Hibernate3/test/org/hibernate/test/ops/Competition.hbm.xml 2007-01-09 16:04:16
UTC (rev 11037)
@@ -13,9 +13,7 @@
<id name="id">
<generator class="native"/>
</id>
- <list name="competitors"
- cascade="persist,merge"
- table="COMPET_ION_OR">
+ <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" />
Modified: trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2007-01-09 16:03:50 UTC
(rev 11036)
+++ trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2007-01-09 16:04:16 UTC
(rev 11037)
@@ -570,28 +570,44 @@
cleanup();
}
- public void testMergeManyToManyWithColelctionDeference() throws Exception {
+ public void testMergeManyToManyWithCollectionDeference() throws Exception {
+ // setup base data...
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
Competition competition = new Competition();
- competition.getCompetitors().add( new Competitor("Name") );
+ competition.getCompetitors().add( new Competitor( "Name" ) );
competition.getCompetitors().add( new Competitor() );
competition.getCompetitors().add( new Competitor() );
- Session s = openSession( );
- Transaction tx = s.beginTransaction();
s.persist( competition );
- s.flush();
- s.clear();
+ tx.commit();
+ s.close();
+
+ // the competition graph is now detached:
+ // 1) create a new List reference to represent the competitors
+ s = openSession();
+ tx = s.beginTransaction();
List newComp = new ArrayList();
- newComp.add( competition.getCompetitors().get(0) );
+ Competitor originalCompetitor = ( Competitor ) competition.getCompetitors().get( 0 );
+ originalCompetitor.setName( "Name2" );
+ newComp.add( originalCompetitor );
newComp.add( new Competitor() );
- ( (Competitor) newComp.get(0) ).setName( "Name2" );
+ // 2) set that new List reference unto the Competition reference
competition.setCompetitors( newComp );
- competition = (Competition) s.merge( competition );
- s.flush();
- s.clear();
- competition = (Competition) s.get( Competition.class, competition.getId() );
+ // 3) attempt the merge
+ Competition competition2 = ( Competition ) s.merge( competition );
+ tx.commit();
+ s.close();
+
+ assertFalse( competition == competition2 );
+ assertFalse( competition.getCompetitors() == competition2.getCompetitors() );
+ assertEquals( 2, competition2.getCompetitors().size() );
+
+ s = openSession();
+ tx = s.beginTransaction();
+ competition = ( Competition ) s.get( Competition.class, competition.getId() );
assertEquals( 2, competition.getCompetitors().size() );
- assertEquals( "Name2", ( (Competitor) competition.getCompetitors().get(0)
).getName() );
- tx.rollback();
+ s.delete( competition );
+ tx.commit();
s.close();
cleanup();
@@ -600,14 +616,19 @@
private void cleanup() {
Session s = openSession();
s.beginTransaction();
- 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 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();
Show replies by date