Author: jrbauer
Date: Wed Mar 18 04:01:25 2009
New Revision: 755470
URL: http://svn.apache.org/viewvc?rev=755470&view=rev
Log:
OPENJPA-885 Committing code and tests contributed by Dianne Richards.
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaDataImpl.java
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=755470&r1=755469&r2=755470&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
Wed Mar 18 04:01:25 2009
@@ -56,6 +56,7 @@
private int _jpql = JPQL_WARN;
private boolean _storeMapCollectionInEntityAsBlob = false;
private boolean _flushBeforeDetach = false;
+ private boolean _cascadeWithDetach = false;
private boolean _useJPA2DefaultOrderColumnName = true;
private boolean _copyOnDetach = false;
@@ -305,6 +306,32 @@
}
/**
+ * Whether openjpa will always cascade on detach, regardless of the
+ * cascade setting.
+ *
+ * @return true if cascade will always occur, false if cascade will only
+ * occur if it is specified in metadata
+ *
+ * @since 2.0.0
+ */
+ public boolean getCascadeWithDetach() {
+ return _cascadeWithDetach;
+ }
+
+ /**
+ * Whether openjpa should always cascade on detach, regardless of the
+ * cascade setting.
+ *
+ * @param cascadeWithDetach true if cascade should always occur, false if
+ * it should only occur if specified in metadata
+ *
+ * @since 2.0.0
+ */
+ public void setCascadeWithDetach(boolean cascadeWithDetach) {
+ _cascadeWithDetach = cascadeWithDetach;
+ }
+
+ /**
* Whether OpenJPA should use the new default order column name defined
* by JPA 2.0: name; "_"; "ORDER" or the pre-JPA 2.0 default name "ordr".
*
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java?rev=755470&r1=755469&r2=755470&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
Wed Mar 18 04:01:25 2009
@@ -36,7 +36,6 @@
import org.apache.commons.collections.map.IdentityMap;
import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.conf.DetachOptions;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.event.CallbackModes;
import org.apache.openjpa.event.LifecycleEvent;
@@ -44,7 +43,6 @@
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.meta.ValueMetaData;
import org.apache.openjpa.util.CallbackException;
import org.apache.openjpa.util.ObjectNotFoundException;
@@ -72,6 +70,7 @@
private final boolean _failFast;
private boolean _flushed = false;
private boolean _flushBeforeDetach;
+ private boolean _cascadeWithDetach;
// if we're not detaching full, we need to track all detached objects;
// if we are, then we use a special field manager for more efficient
@@ -260,18 +259,13 @@
*/
public DetachManager(BrokerImpl broker, boolean full, OpCallbacks call) {
_broker = broker;
- _call = call;
- OpenJPAConfiguration conf = broker.getConfiguration();
- _proxy = conf.getProxyManagerInstance();
- _opts = conf.getDetachStateInstance();
-
- Compatibility compat = conf.getCompatibilityInstance();
- MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
- _copy = full ? false : compat.getCopyOnDetach();
+ _proxy = broker.getConfiguration().getProxyManagerInstance();
+ _opts = broker.getConfiguration().getDetachStateInstance();
_flushed = full;
- _flushBeforeDetach = compat.getFlushBeforeDetach();
- _failFast = (repos.getMetaDataFactory().getDefaults().getCallbackMode()
- & CallbackModes.CALLBACK_FAIL_FAST) != 0;
+ _call = call;
+ _failFast = (broker.getConfiguration().getMetaDataRepositoryInstance().
+ getMetaDataFactory().getDefaults().getCallbackMode()
+ & CallbackModes.CALLBACK_FAIL_FAST) != 0;
// we can only rely on our "full" shortcuts if we know we won't be
// loading any more data
@@ -283,6 +277,16 @@
_detached = new IdentityMap();
_fullFM = null;
}
+ Compatibility compatibility =
+ broker.getConfiguration().getCompatibilityInstance();
+ _flushBeforeDetach = compatibility.getFlushBeforeDetach();
+ _cascadeWithDetach = compatibility.getCascadeWithDetach();
+ if (full) {
+ _copy = false;
+ }
+ else {
+ _copy = compatibility.getCopyOnDetach();;
+ }
}
/**
@@ -710,6 +714,18 @@
return null;
FieldMetaData fmd = sm.getMetaData().getField(field);
+
+ boolean cascade = false;
+ if(_cascadeWithDetach
+ || fmd.getCascadeDetach() ==
+ ValueMetaData.CASCADE_IMMEDIATE
+ || fmd.getKey().getCascadeDetach() ==
+ ValueMetaData.CASCADE_IMMEDIATE
+ || fmd.getElement().getCascadeDetach() ==
+ ValueMetaData.CASCADE_IMMEDIATE) {
+ cascade = true;
+ }
+
Object newVal = null;
switch (fmd.getDeclaredTypeCode()) {
case JavaTypes.ARRAY:
@@ -717,7 +733,9 @@
newVal = _proxy.copyArray(curVal);
else
newVal = curVal;
- detachArray(newVal, fmd);
+ if (cascade) {
+ detachArray(newVal, fmd);
+ }
return newVal;
case JavaTypes.COLLECTION:
if (_copy) {
@@ -731,7 +749,10 @@
newVal = _proxy.copyCollection((Collection) curVal);
} else
newVal = curVal;
- detachCollection((Collection) newVal, (Collection) curVal,
fmd);
+ if (cascade) {
+ detachCollection((Collection) newVal, (Collection) curVal,
+ fmd);
+ }
return reproxy(newVal, field);
case JavaTypes.MAP:
if (_copy) {
@@ -746,7 +767,9 @@
newVal = _proxy.copyMap((Map) curVal);
} else
newVal = curVal;
- detachMap((Map) newVal, (Map) curVal, fmd);
+ if (cascade) {
+ detachMap((Map) newVal, (Map) curVal, fmd);
+ }
return reproxy(newVal, field);
case JavaTypes.CALENDAR:
newVal = (_copy) ? _proxy.copyCalendar((Calendar) curVal) :
@@ -761,7 +784,10 @@
return reproxy((newVal == null) ? curVal : newVal, field);
case JavaTypes.PC:
case JavaTypes.PC_UNTYPED:
- return detachInternal(curVal);
+ if (cascade) {
+ return detachInternal(curVal);
+ }
+ return curVal;
default:
return curVal;
}
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaDataImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaDataImpl.java?rev=755470&r1=755469&r2=755470&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaDataImpl.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaDataImpl.java
Wed Mar 18 04:01:25 2009
@@ -259,6 +259,9 @@
}
public int getCascadeDetach() {
+ if (_owner.getManagement() != FieldMetaData.MANAGE_PERSISTENT
+ || !isDeclaredTypePC()) // detach acts on declared type
+ return CASCADE_NONE;
if (isEmbedded())
return CASCADE_IMMEDIATE;
return _detach;