Author: ppoddar
Date: Mon Mar  9 23:27:50 2009
New Revision: 751910

URL: http://svn.apache.org/viewvc?rev=751910&view=rev
Log:
OPENJPA-968: Change default detach to be in-place rather than copy to align 
with JPA 2.0

Added:
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
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/FieldMetaData.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaData.java
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaDataImpl.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestNoCascadeOneToOneMerge.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/oracle/TestAutoIncrement.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestFlushBeforeDetach.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.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=751910&r1=751909&r2=751910&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
 Mon Mar  9 23:27:50 2009
@@ -55,9 +55,10 @@
     private boolean _nonOptimisticVersionCheck = false;
     private int _jpql = JPQL_WARN;
     private boolean _storeMapCollectionInEntityAsBlob = false;
-    private boolean _flushBeforeDetach = true; 
+    private boolean _flushBeforeDetach = false; 
     private boolean _useJPA2DefaultOrderColumnName = true;
-
+    private boolean _copyOnDetach = false;
+    
     /**
      * Whether to require exact identity value types when creating object
      * ids from a class and value. Defaults to false.
@@ -269,6 +270,39 @@
     public void setFlushBeforeDetach(boolean beforeDetach) {
         _flushBeforeDetach = beforeDetach;
     }
+    
+    /**
+     * Affirms if detached entities are copy of the managed instances.
+     * Before this option is introduced, detached entities were by default 
+     * copies of the managed entities unless the entire cache is detached, 
only 
+     * then the detachment was in-place.
+     * This option changes the default behavior such that detachment is now
+     * in-place by default. To emulate the previous copy-on-detach behavior
+     * set this option to true.  
+     * 
+     * If the entire cache is being detached (when the persistence context is
+     * closed, for example), the detachement 
+     * 
+     * @since 2.0.0
+     */
+    public boolean getCopyOnDetach() {
+        return _copyOnDetach;
+    }
+    
+    /**
+     * Sets if detached entities are copy of the managed instances.
+     * Before this option is introduced, detached entities were by default 
+     * copies of the managed entities unless the entire cache is detached, 
only 
+     * then the detachment was in-place.
+     * This option changes the default behavior such that detachment is now
+     * in-place by default. To emulate the previous copy-on-detach behavior
+     * set this option to true.   
+     * 
+     * @since 2.0.0
+     */
+    public void setCopyOnDetach(boolean copyOnDetach) {
+        _copyOnDetach = copyOnDetach;
+    }
 
     /**
      * Whether OpenJPA should use the new default order column name defined

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=751910&r1=751909&r2=751910&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
 Mon Mar  9 23:27:50 2009
@@ -34,7 +34,9 @@
 import java.util.Map;
 
 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;
@@ -42,6 +44,8 @@
 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;
 import org.apache.openjpa.util.Proxy;
@@ -173,7 +177,7 @@
 
             // clear lrs fields
             FieldMetaData[] fmds = sm.getMetaData().getFields();
-            for (int i = 0; i < fmds.length; i++)
+            for (int i = 0; i < fmds.length; i++) 
                 if (fmds[i].isLRS())
                     idxs.clear(i);
         }
@@ -244,6 +248,7 @@
                 idxs.set(i);
         }
     }
+    
 
     /**
      * Constructor.
@@ -255,16 +260,20 @@
      */
     public DetachManager(BrokerImpl broker, boolean full, OpCallbacks call) {
         _broker = broker;
-        _proxy = broker.getConfiguration().getProxyManagerInstance();
-        _opts = broker.getConfiguration().getDetachStateInstance();
-        _copy = !full;
-        _flushed = full;
         _call = call;
-        _failFast = (broker.getConfiguration().getMetaDataRepositoryInstance().
-            getMetaDataFactory().getDefaults().getCallbackMode()
-            & CallbackModes.CALLBACK_FAIL_FAST) != 0;
+        OpenJPAConfiguration conf = broker.getConfiguration();
+        _proxy = conf.getProxyManagerInstance();
+        _opts = conf.getDetachStateInstance();
+        
+        Compatibility compat = conf.getCompatibilityInstance();
+        MetaDataRepository repos  = conf.getMetaDataRepositoryInstance();
+        _copy = full ? false : compat.getCopyOnDetach();
+        _flushed = full;
+        _flushBeforeDetach = compat.getFlushBeforeDetach();
+        _failFast = (repos.getMetaDataFactory().getDefaults().getCallbackMode()
+                   & CallbackModes.CALLBACK_FAIL_FAST) != 0;
 
-        // we can only rely on our "all" shortcuts if we know we won't be
+        // we can only rely on our "full" shortcuts if we know we won't be
         // loading any more data
         _full = full && broker.getDetachState() == DetachState.DETACH_LOADED;
         if (_full) {
@@ -274,9 +283,6 @@
             _detached = new IdentityMap();
             _fullFM = null;
         }
-        _flushBeforeDetach =
-                broker.getConfiguration().getCompatibilityInstance()
-                        .getFlushBeforeDetach();
     }
 
     /**
@@ -465,7 +471,7 @@
         if (!Boolean.FALSE.equals(sm.getMetaData().usesDetachedState()))
             detachedPC.pcSetDetachedState(getDetachedState(sm, fields));
         if (!_copy)
-            sm.release(false, !_copy);
+            sm.release(false, true);
         if (detSM != null)
             detachedPC.pcReplaceStateManager(detSM);
         return detachedPC;

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
 Mon Mar  9 23:27:50 2009
@@ -2015,6 +2015,14 @@
     public void setCascadeAttach(int attach) {
         _val.setCascadeAttach(attach);
     }
+    
+    public int getCascadeDetach() {
+        return _val.getCascadeDetach();
+    }
+
+    public void setCascadeDetach(int detach) {
+        _val.setCascadeDetach(detach);
+    }
 
     public int getCascadeRefresh() {
         return _val.getCascadeRefresh();

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaData.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaData.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaData.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ValueMetaData.java
 Mon Mar  9 23:27:50 2009
@@ -215,6 +215,25 @@
      * @see #getCascadeAttach
      */
     public void setCascadeAttach(int cascade);
+    
+    /**
+     * Cascade behavior for detach operation. Only applies to
+     * persistence-capable values. Options are:<br />
+     * <ul>
+     * <li><code>CASCADE_NONE</code>: No cascades of detach. Relation
+     * remains attached.</li>
+     * <li><code>CASCADE_IMMEDIATE</code>: Value is detached immediately.</li>
+     * </ul>
+     */
+    public int getCascadeDetach();
+
+    /**
+     * Cascade behavior for detach operation.
+     *
+     * @see #getCascadeDetach
+     */
+    public void setCascadeDetach(int cascade);
+
 
     /**
      * Cascade behavior for refresh operation. Only applies to

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=751910&r1=751909&r2=751910&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
 Mon Mar  9 23:27:50 2009
@@ -50,6 +50,7 @@
     private int _delete = CASCADE_NONE;
     private int _persist = CASCADE_AUTO;
     private int _attach = CASCADE_IMMEDIATE;
+    private int _detach = CASCADE_AUTO;
     private int _refresh = CASCADE_AUTO;
     private boolean _serialized = false;
     private Boolean _embedded = null;
@@ -257,6 +258,16 @@
         _attach = attach;
     }
 
+    public int getCascadeDetach() {
+        if (isEmbedded())
+            return CASCADE_IMMEDIATE;
+        return _detach;
+    }
+
+    public void setCascadeDetach(int detach) {
+        _detach = detach;
+    }
+
     public int getCascadeRefresh() {
         if (_owner.getManagement() != FieldMetaData.MANAGE_PERSISTENT
             || !isDeclaredTypePC()) // refresh acts on declared type
@@ -451,6 +462,7 @@
         _delete = vmd.getCascadeDelete();
         _persist = vmd.getCascadePersist();
         _attach = vmd.getCascadeAttach();
+        _detach = vmd.getCascadeDetach();
         _refresh = vmd.getCascadeRefresh();
         _typeOverride = vmd.getTypeOverride();
         _serialized = vmd.isSerialized();

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java?rev=751910&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
 Mon Mar  9 23:27:50 2009
@@ -0,0 +1,200 @@
+package org.apache.openjpa.persistence.detachment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.detachment.model.DMCustomer;
+import org.apache.openjpa.persistence.detachment.model.DMCustomerInventory;
+import org.apache.openjpa.persistence.detachment.model.DMItem;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests detachment behavior according to JPA 2.0 Specification. The primary
+ * changes in detachment behavior from the existing OpenJPA behavior are
+ * i. detach(x) does not flush if x is dirty
+ * ii. detach(x) removes x from persistence context
+ * iii. detach(x) propagates via CascadeType.DETACH. It is not clear how that
+ * impacts the detach graph. So currently, detach graph is same as 'loaded'.   
+ * 
+ * The test uses a 'domain model' with following cascade relation
+ * 
+ *            ALL                 PERSIST, MERGE, REFRESH
+ * Customer --------> Inventory   ----------------------> Item
+ *          <-------
+ *            MERGE
+ *            
+ * @author Pinaki Poddar
+ *
+ */
+public class TestDetach extends SingleEMFTestCase {
+    private OpenJPAEntityManager em;
+    private DMCustomer root;
+    
+    public void setUp() {
+        super.setUp(DMCustomer.class, DMCustomerInventory.class, DMItem.class,
+            CLEAR_TABLES);
+        em = emf.createEntityManager();
+        root = createData();
+    }
+    
+    public void testDetachCascadeIsSet() {
+        MetaDataRepository repos = emf.getConfiguration()
+                                      .getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getCachedMetaData(DMCustomer.class);
+        assertEquals(ValueMetaData.CASCADE_IMMEDIATE, 
meta.getField("firstName").getCascadeDetach());
+        assertEquals(ValueMetaData.CASCADE_IMMEDIATE, 
meta.getField("customerInventories").getElement().getCascadeDetach());
+        
+        meta = repos.getCachedMetaData(DMCustomerInventory.class);
+        assertEquals(ValueMetaData.CASCADE_NONE, 
meta.getField("customer").getCascadeDetach());
+        assertEquals(ValueMetaData.CASCADE_NONE, 
meta.getField("item").getCascadeDetach());
+        
+    }
+    
+    public void testDetachRemovesEntityAndCascadedRelationFromContext() {
+        em.getTransaction().begin();
+        
+        DMCustomer pc = em.find(DMCustomer.class, root.getId());
+        List<DMCustomerInventory> inventories = pc.getCustomerInventories();
+        DMItem item = inventories.get(0).getItem();
+        
+        assertNotDetached(pc);
+        for (DMCustomerInventory i : inventories) assertNotDetached(i);
+        assertNotDetached(item);   
+        
+        em.clear(pc);
+        
+        assertDetached(pc);
+        for (DMCustomerInventory i : inventories) assertDetached(i);
+        
+        em.getTransaction().rollback();
+        
+        assertNotNull(pc.getFirstName());
+    }
+    
+    public void testDetachingDirtyEntityDoesNotImplicitlyFlush() {
+        em.getTransaction().begin();
+        DMCustomer pc = em.find(DMCustomer.class, root.getId());
+        String original = pc.getLastName();
+        pc.setLastName("Changed That Should not be Saved");
+ 
+        em.clear(pc);
+        em.getTransaction().commit();
+        
+        DMCustomer pc2 = em.find(DMCustomer.class, root.getId());
+        assertNotNull(pc2);
+        assertEquals(original, pc2.getLastName());
+    }
+    
+    public void testDetachingNewEntityIsIgnored() {
+        em.getTransaction().begin();
+        DMCustomer pc = em.find(DMCustomer.class, root.getId());
+        List<DMCustomerInventory> inventories = pc.getCustomerInventories();
+        
+        DMCustomer newPC = new DMCustomer();
+        newPC.setCustomerInventories(inventories);
+        for (DMCustomerInventory inventory : inventories)
+            inventory.setCustomer(newPC);
+        
+        em.clear(newPC);
+        for (DMCustomerInventory inventory : inventories) {
+            assertNotDetached(inventory);
+        }
+        em.getTransaction().rollback();
+    }
+    
+    public void testDetachingDetachedEntityIsIgnored() {
+        em.getTransaction().begin();
+        DMCustomer pc = em.find(DMCustomer.class, root.getId());
+        List<DMCustomerInventory> inventories = pc.getCustomerInventories();
+        
+        em.clear(pc);
+        DMCustomer detached = pc;
+        assertDetached(detached);
+        for (DMCustomerInventory inventory : inventories) {
+            assertDetached(inventory);
+        }
+        
+        List<DMCustomerInventory> newInventories = new 
ArrayList<DMCustomerInventory>();
+        newInventories.addAll(inventories);
+        DMCustomerInventory newInventory = new DMCustomerInventory();
+        newInventory.setCustomer(detached);
+        newInventories.add(newInventory);
+        detached.setCustomerInventories(newInventories);
+        em.persist(newInventory);
+        assertNotDetached(newInventory);
+        
+        em.clear(detached);
+        assertDetached(detached);
+        assertEquals(inventories.size()+1, newInventories.size());
+        for (DMCustomerInventory inventory : newInventories) {
+            if (inventory == newInventory)
+                assertNotDetached(inventory);
+            else
+                assertDetached(inventory);
+        }
+        em.getTransaction().rollback();
+    }
+    
+    
+    public void testFlushingBeforeDetachingSavesChange() {
+        
+    }
+    
+    public void testManagedEntityContinuesToReferDetachedEntities() {
+        em.getTransaction().begin();
+        
+        DMCustomer pc = em.find(DMCustomer.class, root.getId());
+        List<DMCustomerInventory> inventories = pc.getCustomerInventories();
+        DMItem item = inventories.get(1).getItem();
+        
+        em.clear(inventories.get(0));
+        
+        DMCustomerInventory attached0 = inventories.get(0);
+        DMCustomerInventory attached1 = inventories.get(1);
+        
+        assertSame(pc.getCustomerInventories().get(0), attached0);
+        assertSame(pc.getCustomerInventories().get(1), attached1);
+        
+        em.getTransaction().rollback();
+    }
+    
+    DMCustomer createData() {
+        DMItem item1 = new DMItem();
+        DMItem item2 = new DMItem();
+        item1.setName("item-1"); item1.setPrice(100.0);
+        item2.setName("item-2"); item2.setPrice(200.0);
+        
+        DMCustomerInventory inventory1 = new DMCustomerInventory();
+        DMCustomerInventory inventory2 = new DMCustomerInventory();
+        inventory1.setItem(item1); inventory1.setQuantity(10);
+        inventory2.setItem(item2); inventory2.setQuantity(20);
+        DMCustomer customer = new DMCustomer();
+        customer.setFirstName("Detached"); customer.setLastName("Customer");
+        customer.setCustomerInventories(Arrays.asList(
+            new DMCustomerInventory[]{inventory1,inventory2}));
+        inventory1.setCustomer(customer);
+        inventory2.setCustomer(customer);
+        
+        em.getTransaction().begin();
+        em.persist(customer);
+        em.getTransaction().commit();
+        em.clear();
+        
+        return customer;
+    }
+    
+    void assertDetached(Object pc) {
+        assertTrue(pc + " should be detached", em.isDetached(pc));
+        assertFalse(pc + " should not be in cache", em.contains(pc));
+    }
+    
+    void assertNotDetached(Object pc) {
+        assertFalse(pc + " should not be detached", em.isDetached(pc));
+        assertTrue(pc + " should be in cache", em.contains(pc));
+    }
+}

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestNoCascadeOneToOneMerge.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestNoCascadeOneToOneMerge.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestNoCascadeOneToOneMerge.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestNoCascadeOneToOneMerge.java
 Mon Mar  9 23:27:50 2009
@@ -40,7 +40,9 @@
     private int b2_id;
 
     public void setUp() {
-        setUp(SimpleA.class, SimpleRef.class, SimpleB.class, SimpleC.class, 
CLEAR_TABLES);
+        setUp(SimpleA.class, SimpleRef.class, SimpleB.class, SimpleC.class, 
+            "openjpa.Compatibility", 
"FlushBeforeDetach=true,CopyOnDetach=true",
+            CLEAR_TABLES);
         createEntities();
     }
 

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
 Mon Mar  9 23:27:50 2009
@@ -18,7 +18,7 @@
  */
 package org.apache.openjpa.persistence.detachment.model;
 
-import javax.persistence.CascadeType;
+import static javax.persistence.CascadeType.*;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
@@ -29,12 +29,12 @@
     private static long idCounter = System.currentTimeMillis();
     @Id private long id = idCounter++;
 
-    @ManyToOne(cascade=CascadeType.ALL)
+    @ManyToOne(cascade={PERSIST, MERGE, REFRESH})
     @JoinColumn(name = "CI_ITEMID")
     private DMItem  item;    
     private int quantity;
 
-    @ManyToOne(cascade=CascadeType.MERGE)
+    @ManyToOne(cascade=MERGE)
     @JoinColumn(name="CI_CUSTOMERID")
     private DMCustomer customer;
 

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/oracle/TestAutoIncrement.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/oracle/TestAutoIncrement.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/oracle/TestAutoIncrement.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/oracle/TestAutoIncrement.java
 Mon Mar  9 23:27:50 2009
@@ -20,6 +20,7 @@
 
 import javax.persistence.EntityManager;
 
+import org.apache.openjpa.persistence.test.DatabasePlatform;
 import org.apache.openjpa.persistence.test.SingleEMFTestCase;
 
 /**
@@ -37,14 +38,12 @@
  * @author Pinaki Poddar
  * 
  */
+
+...@databaseplatform("oracle.jdbc.driver.OracleDriver")
 public class TestAutoIncrement extends SingleEMFTestCase {
        private static String PLATFORM = "oracle";
 
        public void setUp() throws Exception {
-           // run with -Dplatform= ${PLATFORM} to activate
-               if (!isTargetPlatform(PLATFORM)) {
-                       return;
-               }
                if 
("testAutoIncrementIdentityWithNamedSequence".equals(getName())) {
                        super.setUp(CLEAR_TABLES, PObject.class,
                            "openjpa.jdbc.DBDictionary",

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestFlushBeforeDetach.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestFlushBeforeDetach.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestFlushBeforeDetach.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestFlushBeforeDetach.java
 Mon Mar  9 23:27:50 2009
@@ -36,7 +36,7 @@
     
     public void setUp() {
       setUp(Item.class,"openjpa.Compatibility", 
-                "default(flushBeforeDetach=false)");
+                "default(flushBeforeDetach=false,copyOnDetach=true)");
         persistSampleEntity();
     }
     

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 Mon Mar  9 23:27:50 2009
@@ -1577,10 +1577,13 @@
                 vmd.setCascadePersist(ValueMetaData.CASCADE_IMMEDIATE);
             if (cascade == CascadeType.ALL || cascade == CascadeType.MERGE)
                 vmd.setCascadeAttach(ValueMetaData.CASCADE_IMMEDIATE);
+            if (cascade == CascadeType.ALL || cascade == CascadeType.CLEAR)
+                vmd.setCascadeDetach(ValueMetaData.CASCADE_IMMEDIATE);
             if (cascade == CascadeType.ALL || cascade == CascadeType.REFRESH)
                 vmd.setCascadeRefresh(ValueMetaData.CASCADE_IMMEDIATE);
         }
     }
+    
     private void setOrphanRemoval(ValueMetaData vmd, boolean orphanRemoval) {
         if (orphanRemoval) 
             vmd.setCascadeDelete(ValueMetaData.CASCADE_AUTO);

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
 Mon Mar  9 23:27:50 2009
@@ -1335,6 +1335,10 @@
                     throw new UserException(_loc.get("not-managed",
                         Exceptions.toString(obj))).setFailedObject(obj);
                 break;
+            case OP_DETACH:
+                if (sm == null || !sm.isPersistent() || sm.isDetached())
+                    return ACT_NONE;
+                break;
         }
         return ACT_RUN | ACT_CASCADE;
     }
@@ -1492,8 +1496,7 @@
     }
 
     public void clear(Object entity) {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
+        _broker.detach(entity, this);
     }
 
     public Query createQuery(QueryDefinition qdef) {

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
 Mon Mar  9 23:27:50 2009
@@ -221,12 +221,13 @@
     }
 
     /**
-     * Turns off auto cascading of persist, refresh, attach.
+     * Turns off auto cascading of persist, refresh, attach, detach.
      */
     static void setCascadeNone(ValueMetaData vmd) {
         vmd.setCascadePersist(ValueMetaData.CASCADE_NONE);
         vmd.setCascadeRefresh(ValueMetaData.CASCADE_NONE);
         vmd.setCascadeAttach(ValueMetaData.CASCADE_NONE);
+        vmd.setCascadeDetach(ValueMetaData.CASCADE_NONE);
     }
 
     @Override

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=751910&r1=751909&r2=751910&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
 Mon Mar  9 23:27:50 2009
@@ -1156,6 +1156,9 @@
                 case MERGE:
                     vmd.setCascadeAttach(ValueMetaData.CASCADE_IMMEDIATE);
                     break;
+                case CLEAR:
+                    vmd.setCascadeDetach(ValueMetaData.CASCADE_IMMEDIATE);
+                    break;
                 case REMOVE:
                     vmd.setCascadeDelete(ValueMetaData.CASCADE_IMMEDIATE);
                     break;


Reply via email to