Author: gbadner
Date: 2010-07-19 21:04:51 -0400 (Mon, 19 Jul 2010)
New Revision: 19968
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java
core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/cascade/BidirectionalOneToManyCascadeTest.java
Log:
HHH-2269 : Many-to-one cascade fails with TransientObjectException if inverse collection
is CascadeType.DELETE_ORPHAN
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java
===================================================================
---
core/branches/Branch_3_5/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java 2010-07-19
22:09:56 UTC (rev 19967)
+++
core/branches/Branch_3_5/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java 2010-07-20
01:04:51 UTC (rev 19968)
@@ -36,14 +36,17 @@
import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException;
import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.ForeignKeys;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Status;
import org.hibernate.engine.TypedValue;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.type.Type;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.EmptyIterator;
+import org.hibernate.util.IdentitySet;
import org.hibernate.util.MarkerObject;
/**
@@ -905,20 +908,29 @@
// collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for
fast access
java.util.Set currentIds = new HashSet();
+ java.util.Set currentSaving = new IdentitySet();
for ( Iterator it=currentElements.iterator(); it.hasNext(); ) {
Object current = it.next();
if ( current!=null && ForeignKeys.isNotTransient(entityName, current, null,
session) ) {
- Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName,
current, session);
- currentIds.add( new TypedValue( idType, currentId, session.getEntityMode() ) );
+ EntityEntry ee = session.getPersistenceContext().getEntry( current );
+ if ( ee != null && ee.getStatus() == Status.SAVING ) {
+ currentSaving.add( current );
+ }
+ else {
+ Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName,
current, session);
+ currentIds.add( new TypedValue( idType, currentId, session.getEntityMode() ) );
+ }
}
}
// iterate over the *old* list
for ( Iterator it=oldElements.iterator(); it.hasNext(); ) {
Object old = it.next();
- Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, old,
session);
- if ( !currentIds.contains( new TypedValue( idType, oldId, session.getEntityMode() ) )
) {
- res.add(old);
+ if ( ! currentSaving.contains( old ) ) {
+ Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, old,
session);
+ if ( !currentIds.contains( new TypedValue( idType, oldId, session.getEntityMode() ) )
) {
+ res.add(old);
+ }
}
}
Modified:
core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/cascade/BidirectionalOneToManyCascadeTest.java
===================================================================
---
core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/cascade/BidirectionalOneToManyCascadeTest.java 2010-07-19
22:09:56 UTC (rev 19967)
+++
core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/cascade/BidirectionalOneToManyCascadeTest.java 2010-07-20
01:04:51 UTC (rev 19968)
@@ -118,10 +118,8 @@
* Saves the child object with the parent when the one-to-many association
* uses cascade="all-delete-orphan" and the many-to-one association uses
* cascade="all"
- * <p/>
- * This test is known to fail. See HHH-2269.
*/
- public void testSaveOrphanDeleteChildWithParentFailureExpected() {
+ public void testSaveOrphanDeleteChildWithParent() {
Session session = openSession();
Transaction txn = session.beginTransaction();
Parent parent = new Parent();