mirror of
https://github.com/apache/openjpa.git
synced 2025-02-23 19:05:00 +00:00
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:
parent
80be256e13
commit
33ed6bfb7f
@ -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();
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user