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();
}