You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2008/10/14 19:22:40 UTC

svn commit: r704585 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java

Author: fancy
Date: Tue Oct 14 10:22:39 2008
New Revision: 704585

URL: http://svn.apache.org/viewvc?rev=704585&view=rev
Log:
OPENJPA-744 Extra SQL on LAZY/EAGER  ManyToOne relation
Further improved for performance when OneToMany is fetch EAGER, the inverse ManyToOne relations are set such that relation fields in entities after detach remain valid.

Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=704585&r1=704584&r2=704585&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Tue Oct 14 10:22:39 2008
@@ -35,6 +35,7 @@
 
 import javax.sql.DataSource;
 
+import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.event.OrphanedKeyAction;
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.jdbc.conf.QuerySQLCacheValue;
@@ -355,6 +356,14 @@
                 Object mappedByObject = info.result.getMappedByValue();
                 if (mappedByFieldMapping != null && mappedByObject != null)
                     if (mappedByObject instanceof OpenJPAId)
+                        // The inverse relation can not be set since
+                        // we are eagerly loading this sm for
+                        // a sm owner that is still in the process of 
+                        // initializing itself.
+                        // Remember owner oid by setIntermediate().
+                        // The inverse relation is set later by
+                        // setInverseRelation() when the sm owner is fully
+                        // initialized.
                         sm.setIntermediate(mappedByFieldMapping.getIndex(),
                             mappedByObject);
                     else
@@ -366,6 +375,7 @@
                 mapping = (ClassMapping) sm.getMetaData();
                 load(mapping, sm, fetch, res);
                 getVersion(mapping, sm, res);
+                setInverseRelation(sm, mapping, res);
             }
             return true;
         } finally {
@@ -374,6 +384,47 @@
         }
     }
 
+    private void setInverseRelation(OpenJPAStateManager owner,
+        ClassMapping mapping, Result res) {
+        FieldMapping[] fms = mapping.getFieldMappings();
+
+        // At this point, the owner is fully initialized.
+        // Check if the owner has eagerly loaded ToMany relations.
+        for (int i = 0; i < fms.length; i++) {
+            if (res.getEager(fms[i]) != null) {
+                Object coll =  owner.fetchObject(fms[i].getIndex());
+                if (coll instanceof Collection && 
+                    ((Collection) coll).size() > 0) {
+                    // Found eagerly loaded collection.
+                    // Publisher (1) <==>  (M) Magazine
+                    //    publisher has a EAGER OneToMany relation
+                    //    magazine has a EAGER or LAZY ManyToOne publisher
+                    // For each member (Magazine) in the collection, 
+                    // set its inverse relation (Publisher).
+                    for (Iterator itr = ((Collection) coll).iterator();
+                        itr.hasNext();) {
+                        PersistenceCapable pc = (PersistenceCapable) itr.next();
+                        OpenJPAStateManager sm = (OpenJPAStateManager) pc.
+                            pcGetStateManager();
+                        FieldMapping[] fmd = ((ClassMapping) sm.getMetaData()).
+                            getFieldMappings();
+                        for (int j = 0; j < fmd.length; j++) {
+                            Object oid = sm.getIntermediate(fmd[j].getIndex());
+                            // if oid was setIntermediate() previously
+                            // and it is the same as the owner,
+                            // then set the inverse relation
+                            if (oid != null &&
+                                oid.equals(owner.getObjectId())) {
+                                sm.storeObject(fmd[j].getIndex(),
+                                    owner.getPersistenceCapable());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     protected void setMappedBy(OpenJPAStateManager sm,
         FieldMapping mappedByFieldMapping, Object mappedByObject) {
         ClassMapping mapping = (ClassMapping) sm.getMetaData();

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java?rev=704585&r1=704584&r2=704585&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestInverseEagerSQL.java Tue Oct 14 10:22:39 2008
@@ -235,6 +235,7 @@
         assertEquals(2, sql.size());
 
         sql.clear();
+        em.clear();
         for (int i = 0; i < list.size(); i++) {
             Publisher p = (Publisher) list.get(i);
             Set<Magazine> magazines = p.getMagazineCollection();