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;


Reply via email to