JPA2 Query support for embeddables; nested embeddables; relationships from embeddables

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@761031 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Catalina Wei 2009-04-01 19:53:54 +00:00
parent 80be256e13
commit 33ed6bfb7f
3 changed files with 174 additions and 40 deletions

View File

@ -44,7 +44,6 @@ import org.apache.openjpa.jdbc.meta.Embeddable;
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.jdbc.sql.Select;
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 @@ public class EmbedFieldStrategy
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 @@ public class EmbedFieldStrategy
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 @@ public class EmbedFieldStrategy
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();
}
/////////////////////////////

View File

@ -148,6 +148,8 @@ public class StateManagerImpl
// 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 @@ public class StateManagerImpl
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 @@ public class StateManagerImpl
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 @@ public class StateManagerImpl
*/
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;

View File

@ -964,10 +964,9 @@ public class TestEmbeddable extends SingleEMFTestCase {
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 class TestEmbeddable extends SingleEMFTestCase {
*/
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 @@ public class TestEmbeddable extends SingleEMFTestCase {
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 class TestEmbeddable extends SingleEMFTestCase {
*/
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 class TestEmbeddable extends SingleEMFTestCase {
*/
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 @@ public class TestEmbeddable extends SingleEMFTestCase {
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 class TestEmbeddable extends SingleEMFTestCase {
*/
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 @@ public class TestEmbeddable extends SingleEMFTestCase {
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 @@ public class TestEmbeddable extends SingleEMFTestCase {
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();
}