diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/AutoDetachValue.java b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/AutoDetachValue.java index b2c4a066f..6ab824bed 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/conf/AutoDetachValue.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/conf/AutoDetachValue.java @@ -30,11 +30,13 @@ class AutoDetachValue public static final String DETACH_CLOSE = "close"; public static final String DETACH_COMMIT = "commit"; + public static final String DETACH_ROLLBACK= "rollback"; public static final String DETACH_NONTXREAD = "nontx-read"; private static String[] ALIASES = new String[]{ DETACH_CLOSE, String.valueOf(AutoDetach.DETACH_CLOSE), DETACH_COMMIT, String.valueOf(AutoDetach.DETACH_COMMIT), + DETACH_ROLLBACK, String.valueOf(AutoDetach.DETACH_ROLLBACK), DETACH_NONTXREAD, String.valueOf(AutoDetach.DETACH_NONTXREAD), // for compatibility with JDO DetachAllOnCommit "true", String.valueOf(AutoDetach.DETACH_COMMIT), diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AutoDetach.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AutoDetach.java index 36710193c..84376720c 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AutoDetach.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AutoDetach.java @@ -35,4 +35,9 @@ public interface AutoDetach { * nontransactional operation uses a new persistence context in essence. */ public static final int DETACH_NONTXREAD = 2 << 2; + + /** + * Detach context on failed transaction commit / rollback. + */ + public static final int DETACH_ROLLBACK = 2 << 3; } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java index daa053424..6357e320d 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java @@ -1710,7 +1710,7 @@ public class BrokerImpl /** * Mark the operation over. If outermost caller of stack, returns true - * and will detach manageed instances if necessary. + * and will detach managed instances if necessary. */ public boolean endOperation() { try { @@ -1779,6 +1779,10 @@ public class BrokerImpl if ((_autoDetach & DETACH_COMMIT) != 0) detachAllInternal(null); + else if (status == Status.STATUS_ROLLEDBACK + && (_autoDetach & DETACH_ROLLBACK) != 0) { + detachAllInternal(null); + } // in an ee context, it's possible that the user tried to close // us but we didn't actually close because we were waiting on this diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java index 66a67680d..c7f0756e4 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java @@ -40,6 +40,7 @@ import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.util.CallbackException; +import org.apache.openjpa.util.ObjectNotFoundException; import org.apache.openjpa.util.Proxy; import org.apache.openjpa.util.ProxyManager; import org.apache.openjpa.util.UserException; @@ -148,7 +149,12 @@ public class DetachManager exclude = StoreContext.EXCLUDE_ALL; else if (detachMode == DETACH_ALL) loadMode = StateManagerImpl.LOAD_ALL; - sm.load(broker.getFetchConfiguration(), loadMode, exclude, null, false); + try { + sm.load(broker.getFetchConfiguration(), loadMode, exclude, null, + false); + } catch (ObjectNotFoundException onfe) { + // consume the exception + } // create bitset of fields to detach; if mode is all we can use // currently loaded bitset clone, since we know all fields are loaded diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java index e836dd17e..d06b017b7 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java @@ -188,7 +188,8 @@ public class EntityManagerFactoryImpl false); // we should allow the user to specify these settings in conf // regardless of PersistenceContextType - broker.setAutoDetach(AutoDetach.DETACH_CLOSE); + broker.setAutoDetach(AutoDetach.DETACH_CLOSE + | AutoDetach.DETACH_ROLLBACK); broker.setDetachedNew(false); OpenJPAEntityManager em = newEntityManagerImpl(broker);