You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2007/04/06 21:17:45 UTC

svn commit: r526253 - in /incubator/openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/

Author: awhite
Date: Fri Apr  6 12:17:44 2007
New Revision: 526253

URL: http://svn.apache.org/viewvc?view=rev&rev=526253
Log:
OPENJPA-202 : Don't detach LRS fields.  

Added:
    incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/LRSEntity.java   (with props)
    incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLRS.java   (with props)
Modified:
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
    incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java?view=diff&rev=526253&r1=526252&r2=526253
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java Fri Apr  6 12:17:44 2007
@@ -40,6 +40,7 @@
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.JavaTypes;
 import org.apache.openjpa.util.CallbackException;
+import org.apache.openjpa.util.LRSProxy;
 import org.apache.openjpa.util.ObjectNotFoundException;
 import org.apache.openjpa.util.Proxy;
 import org.apache.openjpa.util.ProxyManager;
@@ -163,6 +164,12 @@
                 setFetchGroupFields(broker, sm, idxs);
             else
                 idxs.or(sm.getLoaded());
+
+            // clear lrs fields
+            FieldMetaData[] fmds = sm.getMetaData().getFields();
+            for (int i = 0; i < fmds.length; i++)
+                if (fmds[i].isLRS())
+                    idxs.clear(i);
         }
     }
 
@@ -482,46 +489,49 @@
                 fmd.getTypeCode());
             val = fmd.getFieldValue(val, sm.getBroker());
             switch (fmd.getDeclaredTypeCode()) {
-                case JavaTypes.LONG:
-                case JavaTypes.SHORT:
-                case JavaTypes.INT:
-                case JavaTypes.BYTE:
-                    longval = (val == null) ? 0L : ((Number) val).longValue();
-                    break;
-                case JavaTypes.DOUBLE:
-                case JavaTypes.FLOAT:
-                    dblval = (val == null) ? 0D : ((Number) val).doubleValue();
-                    break;
-                default:
-                    objval = val;
+            case JavaTypes.LONG:
+            case JavaTypes.SHORT:
+            case JavaTypes.INT:
+            case JavaTypes.BYTE:
+                longval = (val == null) ? 0L : ((Number) val).longValue();
+                break;
+            case JavaTypes.DOUBLE:
+            case JavaTypes.FLOAT:
+                dblval = (val == null) ? 0D : ((Number) val).doubleValue();
+                break;
+            default:
+                objval = val;
             }
             sm.replaceField(getDetachedPersistenceCapable(), this,
                 fmd.getIndex());
         }
 
         /**
-         * Unproxies second class object fields; in the future we should
-         * instead set these fields up for change tracking.
+         * Unproxies second class object fields.
          */
         public void reproxy(DetachedStateManager dsm) {
             FieldMetaData[] fmds = sm.getMetaData().getFields();
             for (int i = 0; i < fmds.length; i++) {
                 switch (fmds[i].getDeclaredTypeCode()) {
-                    case JavaTypes.COLLECTION:
-                    case JavaTypes.MAP:
-                    case JavaTypes.DATE:
-                    case JavaTypes.OBJECT:
-                        sm.provideField(getDetachedPersistenceCapable(), this,
-                            i);
-                        if (objval instanceof Proxy) {
-                            Proxy proxy = (Proxy) objval;
-                            if (proxy.getChangeTracker() != null)
-                                proxy.getChangeTracker().stopTracking();
-                            if (dsm == null)
-                                proxy.setOwner(null, -1);
-                            else
-                                proxy.setOwner(dsm, i);
-                        }
+                case JavaTypes.COLLECTION:
+                case JavaTypes.MAP:
+                    // lrs proxies not detached
+                    if (fmds[i].isLRS()) {
+                        objval = null;
+                        sm.replaceField(getDetachedPersistenceCapable(), 
+                            this, i);
+                        break;
+                    }
+                    // no break
+                case JavaTypes.DATE:
+                case JavaTypes.OBJECT:
+                    sm.provideField(getDetachedPersistenceCapable(), this, i);
+                    if (objval instanceof Proxy) {
+                        Proxy proxy = (Proxy) objval;
+                        if (proxy.getChangeTracker() != null)
+                            proxy.getChangeTracker().stopTracking();
+                        proxy.setOwner(dsm, (dsm == null) ? -1 : i);
+                    }
                 }
             }
             clear();
@@ -583,7 +593,7 @@
                     detachField(from, pks[i].getIndex(), true);
                 detachVersion();
                 for (int i = 0; i < fmds.length; i++)
-                    if (!fmds[i].isPrimaryKey() && !fmds[i].isVersion())
+                    if (!fmds[i].isPrimaryKey() && !fmds[i].isVersion()) 
                         detachField(from, i, fgfields.get(i));
             } finally {
                 // clear the StateManager from the target object
@@ -677,61 +687,58 @@
             FieldMetaData fmd = sm.getMetaData().getField(field);
             Object newVal = null;
             switch (fmd.getDeclaredTypeCode()) {
-                case JavaTypes.ARRAY:
-                    if (_copy)
-                        newVal = _proxy.copyArray(curVal);
-                    else
-                        newVal = curVal;
-                    detachArray(newVal, fmd);
-                    return newVal;
-                case JavaTypes.COLLECTION:
-                    if (_copy) {
-                        if (_detSM != null) {
-                            newVal =
-                                _proxy.newCollectionProxy(fmd.getProxyType(),
-                                    fmd.getElement().getDeclaredType(),
-                                    fmd.getInitializer() instanceof Comparator ?
-                                        (Comparator) fmd.getInitializer() :
-                                        null);
-                            ((Collection) newVal).addAll((Collection) curVal);
-                        } else
-                            newVal = _proxy.copyCollection((Collection) curVal);
+            case JavaTypes.ARRAY:
+                if (_copy)
+                    newVal = _proxy.copyArray(curVal);
+                else
+                    newVal = curVal;
+                detachArray(newVal, fmd);
+                return newVal;
+            case JavaTypes.COLLECTION:
+                if (_copy) {
+                    if (_detSM != null) {
+                        newVal = _proxy.newCollectionProxy(fmd.getProxyType(),
+                            fmd.getElement().getDeclaredType(),
+                            fmd.getInitializer() instanceof Comparator ?
+                            (Comparator) fmd.getInitializer() : null);
+                        ((Collection) newVal).addAll((Collection) curVal);
                     } else
-                        newVal = curVal;
-                    detachCollection((Collection) newVal, (Collection) curVal,
-                        fmd);
-                    return reproxy(newVal, field);
-                case JavaTypes.MAP:
-                    if (_copy) {
-                        if (_detSM != null) {
-                            newVal = _proxy.newMapProxy(fmd.getProxyType(),
-                                fmd.getKey().getDeclaredType(),
-                                fmd.getElement().getDeclaredType(),
-                                fmd.getInitializer() instanceof Comparator ?
-                                    (Comparator) fmd.getInitializer() : null);
-                            ((Map) newVal).putAll((Map) curVal);
-                        } else
-                            newVal = _proxy.copyMap((Map) curVal);
+                        newVal = _proxy.copyCollection((Collection) curVal);
+                } else
+                    newVal = curVal;
+                detachCollection((Collection) newVal, (Collection) curVal, fmd);
+                return reproxy(newVal, field);
+            case JavaTypes.MAP:
+                if (_copy) {
+                    if (_detSM != null) {
+                        newVal = _proxy.newMapProxy(fmd.getProxyType(),
+                            fmd.getKey().getDeclaredType(),
+                            fmd.getElement().getDeclaredType(),
+                            fmd.getInitializer() instanceof Comparator ?
+                                (Comparator) fmd.getInitializer() : null);
+                        ((Map) newVal).putAll((Map) curVal);
                     } else
-                        newVal = curVal;
-                    detachMap((Map) newVal, (Map) curVal, fmd);
-                    return reproxy(newVal, field);
-                case JavaTypes.CALENDAR:
-                    newVal = (_copy) ? _proxy.copyCalendar((Calendar) curVal) :
-                        curVal;
-                    return reproxy(newVal, field);
-                case JavaTypes.DATE:
-                    newVal = (_copy) ? _proxy.copyDate((Date) curVal) : curVal;
-                    return reproxy(newVal, field);
-                case JavaTypes.OBJECT:
-                    if (_copy)
-                        newVal = _proxy.copyCustom(curVal);
-                    return reproxy((newVal == null) ? curVal : newVal, field);
-                case JavaTypes.PC:
-                case JavaTypes.PC_UNTYPED:
-                    return detachInternal(curVal);
-                default:
-                    return curVal;
+                        newVal = _proxy.copyMap((Map) curVal);
+                } else
+                    newVal = curVal;
+                detachMap((Map) newVal, (Map) curVal, fmd);
+                return reproxy(newVal, field);
+            case JavaTypes.CALENDAR:
+                newVal = (_copy) ? _proxy.copyCalendar((Calendar) curVal) :
+                    curVal;
+                return reproxy(newVal, field);
+            case JavaTypes.DATE:
+                newVal = (_copy) ? _proxy.copyDate((Date) curVal) : curVal;
+                return reproxy(newVal, field);
+            case JavaTypes.OBJECT:
+                if (_copy)
+                    newVal = _proxy.copyCustom(curVal);
+                return reproxy((newVal == null) ? curVal : newVal, field);
+            case JavaTypes.PC:
+            case JavaTypes.PC_UNTYPED:
+                return detachInternal(curVal);
+            default:
+                return curVal;
             }
         }
 
@@ -752,7 +759,7 @@
          */
         private void detachCollection(Collection coll, Collection orig,
             FieldMetaData fmd) {
-            // coll can be null if not copyable (lrs, for instance)
+            // coll can be null if not copyable
             if (_copy && coll == null)
                 throw new UserException(_loc.get("not-copyable", fmd));
             if (!fmd.getElement().isDeclaredTypePC())
@@ -773,7 +780,7 @@
          * Make sure all the values in the given map are detached.
          */
         private void detachMap(Map map, Map orig, FieldMetaData fmd) {
-            // map can be null if not copyable (lrs, for instance)
+            // map can be null if not copyable
             if (_copy && map == null)
                 throw new UserException(_loc.get("not-copyable", fmd));
             boolean keyPC = fmd.getKey().isDeclaredTypePC();
@@ -788,8 +795,7 @@
                 if (_copy)
                     map.clear();
                 Object key, val;
-                for (Iterator itr = orig.entrySet().iterator(); itr.hasNext();)
-                {
+                for (Iterator itr = orig.entrySet().iterator(); itr.hasNext();){
                     entry = (Map.Entry) itr.next();
                     key = entry.getKey();
                     if (keyPC)

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties?view=diff&rev=526253&r1=526252&r2=526253
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties Fri Apr  6 12:17:44 2007
@@ -138,9 +138,8 @@
 not-detachable: The class "{0}" does not declare the "detachable" metadata \
 	extension, so cannot be detached.
 not-copyable: Attempt to copy field "{0}" failed.  The field is \
-	not copyable.  This can occur with custom SCO types or with large result \
-	set fields.  Only standard or immutable SCO types can be attached and \
-	detached.
+	not copyable.  This can occur with custom SCO types. Only standard or \
+    immutable SCO types can be attached and detached.
 no-detach-object-id: Cannot access the detached object id of class "{0}". \
 	Ensure that the class has the "detachable" metadata extension, and \
 	the the class has been re-enhanced.

Added: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/LRSEntity.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/LRSEntity.java?view=auto&rev=526253
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/LRSEntity.java (added)
+++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/LRSEntity.java Fri Apr  6 12:17:44 2007
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.ManyToMany;
+import javax.persistence.OrderBy;
+
+import org.apache.openjpa.persistence.LRS;
+
+@Entity
+public class LRSEntity {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @ManyToMany
+    @OrderBy("name ASC")
+    @LRS
+    private Collection<BasicEntity> lrsList = new ArrayList<BasicEntity>();
+
+    public long getId() { 
+        return id; 
+    }
+
+    public String getName() { 
+        return name; 
+    }
+
+    public void setName(String name) { 
+        this.name = name; 
+    }
+
+    public Collection<BasicEntity> getLRSList() { 
+        return lrsList; 
+    }
+}

Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/LRSEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/LRSEntity.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLRS.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLRS.java?view=auto&rev=526253
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLRS.java (added)
+++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLRS.java Fri Apr  6 12:17:44 2007
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.persistence.relations;
+
+import java.util.Iterator;
+import javax.persistence.EntityManager;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test LRS relations.
+ *
+ * @author Abe White
+ */
+public class TestLRS
+    extends SingleEMFTestCase {
+
+    private long id;
+
+    public void setUp() {
+        setUp(LRSEntity.class, BasicEntity.class);
+        
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        LRSEntity lrs = new LRSEntity();
+        lrs.setName("lrs"); 
+        for (int i = 1; i <= 3; i++) {
+            BasicEntity basic = new BasicEntity();
+            basic.setName("basic" + i);
+            em.persist(basic);
+            lrs.getLRSList().add(basic);
+        }
+        em.persist(lrs);
+        em.getTransaction().commit();
+        id = lrs.getId();
+        em.close();
+    }
+
+    public void testEMClear() {
+        EntityManager em = emf.createEntityManager();
+        LRSEntity lrs = em.find(LRSEntity.class, id);
+        assertLRS(lrs, "lrs");
+        em.clear();
+        assertNull(lrs.getLRSList());
+        assertMerge(lrs);
+        em.close();
+    }
+
+    public void testEMClose() {
+        EntityManager em = emf.createEntityManager();
+        LRSEntity lrs = em.find(LRSEntity.class, id);
+        assertLRS(lrs, "lrs");
+        em.close();
+        assertNull(lrs.getLRSList());
+        assertMerge(lrs);
+    }
+
+    public void testDetachCopy() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        LRSEntity lrs = em.find(LRSEntity.class, id);
+        assertLRS(lrs, "lrs");
+        lrs = em.detach(lrs); 
+        assertEquals("lrs", lrs.getName());
+        assertNull(lrs.getLRSList());
+        em.close();
+        assertMerge(lrs);
+    }
+
+    private void assertLRS(LRSEntity lrs, String name) {
+        assertNotNull(lrs);
+        assertEquals(name, lrs.getName());
+        assertEquals(3, lrs.getLRSList().size());
+        Iterator itr = lrs.getLRSList().iterator();
+        for (int i = 1; itr.hasNext(); i++) {
+            BasicEntity basic = (BasicEntity) itr.next();
+            assertEquals("basic" + i, basic.getName());
+        }
+        OpenJPAPersistence.close(itr);
+    }
+
+    private void assertMerge(LRSEntity lrs) {
+        lrs.setName("changed");
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        assertLRS(em.merge(lrs), "changed");
+        em.getTransaction().commit();
+        em.close();
+
+        em = emf.createEntityManager();
+        assertLRS(em.find(LRSEntity.class, id), "changed");
+        em.close();
+    }
+
+    public static void main(String[] args) {
+        TestRunner.run(TestLRS.class);
+    }
+}
+

Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestLRS.java
------------------------------------------------------------------------------
    svn:eol-style = native