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 2009/04/01 21:53:55 UTC

svn commit: r761031 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/

Author: fancy
Date: Wed Apr  1 19:53:54 2009
New Revision: 761031

URL: http://svn.apache.org/viewvc?rev=761031&view=rev
Log:
JPA2 Query support for embeddables; nested embeddables; relationships from embeddables

Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java?rev=761031&r1=761030&r2=761031&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java Wed Apr  1 19:53:54 2009
@@ -44,7 +44,6 @@
 import org.apache.openjpa.jdbc.meta.FieldMapping;
 import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
 import org.apache.openjpa.jdbc.meta.RelationId;
-import org.apache.openjpa.jdbc.meta.ValueMapping;
 import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
 import org.apache.openjpa.jdbc.schema.Column;
 import org.apache.openjpa.jdbc.schema.ColumnIO;
@@ -59,17 +58,14 @@
 import org.apache.openjpa.kernel.FetchConfiguration;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
 import org.apache.openjpa.kernel.PCState;
+import org.apache.openjpa.kernel.StateManagerImpl;
 import org.apache.openjpa.kernel.StoreContext;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
 import org.apache.openjpa.meta.ValueMetaData;
-import org.apache.openjpa.util.ApplicationIds;
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.MetaDataException;
-import org.apache.openjpa.util.OpenJPAId;
-import org.apache.openjpa.util.UserException;
 
 /**
  * Mapping for an embedded persistent object.
@@ -419,7 +415,20 @@
         StoreContext ctx = store.getContext();
         OpenJPAStateManager em = ctx.embed(null, null, sm, field);
         sm.storeObject(field.getIndex(), em.getManagedInstance());
+        boolean needsLoad = loadFields(em, store, fetch, res);
 
+        // After loading everything from result, load the rest of the
+        // configured fields if anything is missing.
+        if (needsLoad && 
+            fetch.requiresFetch(field.getFieldMetaData()) == 
+                JDBCFetchConfiguration.FETCH_LOAD) {
+          em.load(fetch);
+        }
+    }
+
+    private boolean loadFields(OpenJPAStateManager em, JDBCStore store,
+        JDBCFetchConfiguration fetch, Result res)
+        throws SQLException {
         FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
         Object eres, processed;
         boolean needsLoad = false;
@@ -444,14 +453,7 @@
                 res.endDataRequest();
             }
         }
-
-        // After loading everything from result, load the rest of the
-        // configured fields if anything is missing.
-        if (needsLoad && 
-            fetch.requiresFetch(field.getFieldMetaData()) == 
-                JDBCFetchConfiguration.FETCH_LOAD) {
-          em.load(fetch);
-        }
+        return needsLoad;
     }
 
     /**
@@ -530,10 +532,34 @@
         return field.join(joins, forceOuter, false);
     }
 
+    /**
+     * Loading embed object without instantiating owner entity
+     */
     public Object loadProjection(JDBCStore store, JDBCFetchConfiguration fetch,
         Result res, Joins joins)
         throws SQLException {
-        throw new UserException(_loc.get("cant-project-owned", field));
+        Boolean isNull = indicatesNull(res);
+        if (isNull == null)
+            return null;
+
+        StoreContext ctx = store.getContext();
+        // load primary key of owner entity
+        Object owner = field.getDefiningMapping().getObjectId(store, res, 
+            null, true, joins);
+        OpenJPAStateManager em = ctx.embed(null, null, null, field);
+        // set owner id
+        ((StateManagerImpl) em).setOwner(owner);
+        boolean needsLoad = loadFields(em, store, fetch, res);
+
+        // After loading everything from result, load the rest of the
+        // configured fields if anything is missing.
+        if (needsLoad && 
+            fetch.requiresFetch(field.getFieldMetaData()) == 
+                JDBCFetchConfiguration.FETCH_LOAD) {
+          em.load(fetch);
+        }
+        
+        return em.getManagedInstance();
     }
     
     /////////////////////////////

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=761031&r1=761030&r2=761031&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Wed Apr  1 19:53:54 2009
@@ -148,6 +148,8 @@
 
     // information about the owner of this instance, if it is embedded
     private StateManagerImpl _owner = null;
+    // for embeddable object from query result
+    private Object _ownerId = null;
     private int _ownerIndex = -1;
     private List _mappedByIdFields = null;
     
@@ -426,6 +428,10 @@
         return _ownerIndex;
     }
 
+    public void setOwner(Object oid) {
+        _ownerId = oid;
+    }
+
     public boolean isEmbedded() {
         // _owner may not be set if embed object is from query result
         return _owner != null || _state instanceof ENonTransState;
@@ -514,6 +520,8 @@
         StateManagerImpl sm = this;
         while (sm.getOwner() != null)
             sm = (StateManagerImpl) sm.getOwner();
+        if (sm.isEmbedded() && sm.getOwner() == null)
+            return sm._ownerId;
         return sm._oid;
     }
 
@@ -594,8 +602,10 @@
      */
     private boolean assignField(int field, boolean preFlushing) {
         OpenJPAStateManager sm = this;
-        while (sm.isEmbedded())
+        while (sm != null && sm.isEmbedded())
             sm = sm.getOwner();
+        if (sm == null)
+            return false;
         if (!sm.isNew() || sm.isFlushed() || sm.isDeleted())
             return false;
 

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java?rev=761031&r1=761030&r2=761031&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java Wed Apr  1 19:53:54 2009
@@ -964,10 +964,9 @@
         List rs = null;
         for (int i = 0; i < query.length; i++) {
             rs = em.createQuery(query[i]).getResultList();
-            if (rs.size() > 0) {
-                Object obj = rs.get(0);
-                assertTrue(obj instanceof String);
-            }
+            assertTrue(rs.size() > 0);
+            Object obj = rs.get(0);
+            assertTrue(obj instanceof String);
             em.clear();
         }
         EntityTransaction tran = em.getTransaction();
@@ -986,6 +985,22 @@
      */
     public void queryEntityA_Embed_ToOne() {
         EntityManager em = emf.createEntityManager();
+        // test select embed object
+        String[] query = {
+            "select a.embed from " +
+                " EntityA_Embed_ToOne a ",
+            "select e from EntityA_Embed_ToOne a " +
+                " join a.embed e join e.b b where e.b.id > 0 order by a.id",
+        };
+        for (int i = 0; i < query.length; i++) {
+            List<Object[]> rs = null;
+            rs = em.createQuery(query[i]).getResultList();
+            assertTrue(rs.size() > 0);
+            Object obj = rs.get(0);
+            assertTrue(obj instanceof Embed_ToOne);
+            assertTrue(((Embed_ToOne) obj).getEntityB() != null);
+            em.clear();
+        }
         EntityTransaction tran = em.getTransaction();
         tran.begin();
         Query q = em.createQuery("select a from EntityA_Embed_ToOne a");
@@ -1017,15 +1032,17 @@
         List<Object[]> rs = null;
         for (int i = 0; i < query.length; i++) {
             rs = em.createQuery(query[i]).getResultList();
-            if (rs.size() > 0) {
-                Object obj = ((Object[]) rs.get(0))[0];
-                assertTrue(obj instanceof Embed_ToOne);
-                switch (i) {
-                case 0:
-                    Object b = ((Object[]) rs.get(0))[1];
-                    assertTrue(b instanceof EntityB1);
-                    break;
-                }
+            assertTrue(rs.size() > 0);
+            Object obj = ((Object[]) rs.get(0))[0];
+            assertTrue(obj instanceof Embed_ToOne);
+            assertTrue(((Embed_ToOne) obj).getEntityB() != null);
+            switch (i) {
+            case 0:
+                Object b = ((Object[]) rs.get(0))[1];
+                assertTrue(b instanceof EntityB1);
+                assertEquals(((EntityB1) b).getId(),
+                    ((Embed_ToOne) obj).getEntityB().getId());
+                break;
             }
             em.clear();
         }
@@ -1045,6 +1062,32 @@
      */
     public void queryEntityA_Embed_ToMany() {
         EntityManager em = emf.createEntityManager();
+        // test select embeddable
+        String query[] = {
+            "select a.embed from EntityA_Embed_ToMany a",
+            "select e from EntityA_Embed_ToMany a join a.embed e",
+            "select b from EntityA_Embed_ToMany a join a.embed.bs" +
+                " b",
+            "select e from EntityA_Embed_ToMany a join a.embed e " +
+                " where e.name1 like '%1'",
+        };
+        List rs = null;
+        for (int i = 0; i < query.length; i++) {
+            rs = em.createQuery(query[i]).getResultList();
+            assertTrue(rs.size() > 0);
+            Object obj = rs.get(0);
+            switch (i) {
+            case 0:
+            case 1:
+                assertTrue(obj instanceof Embed_ToMany);
+                assertTrue(((Embed_ToMany) obj).getEntityBs().size() > 0);
+                break;
+            case 2:
+                assertTrue(obj instanceof EntityB1);
+                break;
+            }
+            em.clear();
+        }
         EntityTransaction tran = em.getTransaction();
         tran.begin();
         Query q = em.createQuery("select a from EntityA_Embed_ToMany a");
@@ -1061,6 +1104,46 @@
      */
     public void queryEntityA_Embed_Embed_ToMany() {
         EntityManager em = emf.createEntityManager();
+        // test select embeddable
+        String query[] = {
+            "select a.embed from EntityA_Embed_Embed_ToMany a",
+            "select a.embed from EntityA_Embed_Embed_ToMany a" +
+                " where a.embed.embed.name1 like '%1' ",
+            "select a.embed.embed from EntityA_Embed_Embed_ToMany a",
+            "select b from EntityA_Embed_Embed_ToMany a join a.embed.embed.bs" +
+                " b",
+            "select a.embed.embed from EntityA_Embed_Embed_ToMany a " +
+                " where a.embed.embed.name1 like '%1'",
+            "select e2 from EntityA_Embed_Embed_ToMany a " +
+                " left join a.embed e1 left join e1.embed e2",
+            "select e2 from EntityA_Embed_Embed_ToMany a " +
+                " join a.embed e1 join e1.embed e2",
+        };
+        List rs = null;
+        for (int i = 0; i < query.length; i++) {
+            rs = em.createQuery(query[i]).getResultList();
+            assertTrue(rs.size() > 0);
+            Object obj = rs.get(0);
+            switch (i) {
+            case 0:
+            case 1:
+                assertTrue(obj instanceof Embed_Embed_ToMany);
+                assertTrue(((Embed_Embed_ToMany) obj).getEmbed().getEntityBs().
+                    size() > 0);
+                break;
+            case 2:
+            case 4:
+            case 5:
+            case 6:
+                assertTrue(obj instanceof Embed_ToMany);
+                assertTrue(((Embed_ToMany) obj).getEntityBs().size() > 0);
+                break;
+            case 3:
+                assertTrue(obj instanceof EntityB1);
+                break;
+            }        
+            em.clear();
+        }
         EntityTransaction tran = em.getTransaction();
         tran.begin();
         Query q = em.createQuery("select a from EntityA_Embed_Embed_ToMany a");
@@ -1091,10 +1174,9 @@
         List<Object[]> rs = null;
         for (int i = 0; i < query.length; i++) {
             rs = em.createQuery(query[i]).getResultList();
-            if (rs.size() > 0) {
-                Object obj = ((Object[]) rs.get(0))[0];
-                assertTrue(obj instanceof Integer);
-            }
+            assertTrue(rs.size() > 0);
+            Object obj = ((Object[]) rs.get(0))[0];
+            assertTrue(obj instanceof Integer);
             em.clear();
         }
 
@@ -1114,6 +1196,24 @@
      */
     public void queryEntityA_Embed_Embed() {
         EntityManager em = emf.createEntityManager();
+        // test select embeddable
+        String query[] = {
+            "select a.embed from EntityA_Embed_Embed a",
+            "select a.embed.embed from EntityA_Embed_Embed a"
+        };
+        List rs = null;
+        for (int i = 0; i < query.length; i++) {
+            rs = em.createQuery(query[i]).getResultList();
+            assertTrue(rs.size() > 0);
+            switch (i) {
+            case 0:
+                assertTrue(rs.get(0) instanceof Embed_Embed);
+                break;
+            case 1:
+                assertTrue(rs.get(0) instanceof Embed);
+            }
+            em.clear();
+        }
         EntityTransaction tran = em.getTransaction();
         tran.begin();
         Query q = em.createQuery("select a from EntityA_Embed_Embed a");
@@ -1141,10 +1241,9 @@
         List rs = null;
         for (int i = 0; i < query.length; i++) {
             rs = em.createQuery(query[i]).getResultList();
-            if (rs != null && rs.size() > 0) {
-                Object obj = ((Object[]) rs.get(0))[0];
-                assertTrue(obj instanceof Embed_Embed);
-            }
+            assertTrue(rs.size() > 0);
+            Object obj = ((Object[]) rs.get(0))[0];
+            assertTrue(obj instanceof Embed_Embed);
         }
         em.clear();
 
@@ -1178,10 +1277,9 @@
         List<Object[]> rs = null;
         for (int i = 0; i < query.length; i++) {
             rs = em.createQuery(query[i]).getResultList();
-            if (rs.size() > 0) {
-                Object obj = ((Object[]) rs.get(0))[0];
-                assertTrue(obj instanceof Embed);
-            }
+            assertTrue(rs.size() > 0);
+            Object obj = ((Object[]) rs.get(0))[0];
+            assertTrue(obj instanceof Embed);
             em.clear();
         }