OPENJPA-956 support elementCollection in FROM clause

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@758868 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Catalina Wei 2009-03-26 21:36:08 +00:00
parent 32796f751b
commit 7e6ca9043e
4 changed files with 44 additions and 9 deletions

View File

@ -32,6 +32,7 @@ import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.FieldMapping; import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes; import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping; import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.strats.HandlerCollectionTableFieldStrategy;
import org.apache.openjpa.jdbc.meta.strats.HandlerRelationMapTableFieldStrategy; import org.apache.openjpa.jdbc.meta.strats.HandlerRelationMapTableFieldStrategy;
import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ForeignKey; import org.apache.openjpa.jdbc.schema.ForeignKey;
@ -253,8 +254,12 @@ public class PCPath
return null; return null;
} else if (_keyPath) } else if (_keyPath)
return pstate.field.getDefiningMapping(); return pstate.field.getDefiningMapping();
if (pstate.field.getElement().getTypeCode() == JavaTypes.PC) if (pstate.field.getElement().getTypeCode() == JavaTypes.PC) {
if (pstate.field.isElementCollection() &&
pstate.field.getElement().isEmbedded())
pstate.isEmbedElementColl = true;
return pstate.field.getElementMapping().getTypeMapping(); return pstate.field.getElementMapping().getTypeMapping();
}
if (pstate.field.getTypeCode() == JavaTypes.PC) if (pstate.field.getTypeCode() == JavaTypes.PC)
return pstate.field.getTypeMapping(); return pstate.field.getTypeMapping();
return null; return null;
@ -291,8 +296,14 @@ public class PCPath
case JavaTypes.ARRAY: case JavaTypes.ARRAY:
case JavaTypes.COLLECTION: case JavaTypes.COLLECTION:
ValueMapping elem = pstate.field.getElementMapping(); ValueMapping elem = pstate.field.getElementMapping();
if (pstate.joinedRel && elem.getTypeCode() == JavaTypes.PC) if (pstate.joinedRel && elem.getTypeCode() == JavaTypes.PC) {
if (pstate.field.isElementCollection() &&
pstate.field.getElement().isEmbedded())
return ((HandlerCollectionTableFieldStrategy)
pstate.field.getStrategy()).getElementColumns(
elem.getTypeMapping());
return elem.getTypeMapping().getPrimaryKeyColumns(); return elem.getTypeMapping().getPrimaryKeyColumns();
}
if (elem.getColumns().length > 0) if (elem.getColumns().length > 0)
return elem.getColumns(); return elem.getColumns();
return pstate.field.getColumns(); return pstate.field.getColumns();
@ -642,6 +653,7 @@ public class PCPath
public FieldMapping cmpfield = null; public FieldMapping cmpfield = null;
public Column[] cols = null; public Column[] cols = null;
public boolean joinedRel = false; public boolean joinedRel = false;
public boolean isEmbedElementColl = false;
public PathExpState(Joins joins) { public PathExpState(Joins joins) {
super(joins); super(joins);
@ -722,7 +734,8 @@ public class PCPath
boolean pks) { boolean pks) {
ClassMapping mapping = getClassMapping(state); ClassMapping mapping = getClassMapping(state);
PathExpState pstate = (PathExpState) state; PathExpState pstate = (PathExpState) state;
if (mapping == null || !pstate.joinedRel || _keyPath) if (mapping == null || !pstate.joinedRel || _keyPath ||
pstate.isEmbedElementColl)
sel.select(getColumns(state), pstate.joins); sel.select(getColumns(state), pstate.joins);
else if (pks) else if (pks)
sel.select(mapping.getPrimaryKeyColumns(), pstate.joins); sel.select(mapping.getPrimaryKeyColumns(), pstate.joins);
@ -784,7 +797,9 @@ public class PCPath
else if (pstate.field.getKey().isEmbedded()) else if (pstate.field.getKey().isEmbedded())
return loadEmbeddedMapKey(ctx, state, res); return loadEmbeddedMapKey(ctx, state, res);
} }
if (pstate.isEmbedElementColl)
return pstate.field.loadProjection(ctx.store, ctx.fetch, res,
pstate.joins);
return res.load(mapping, ctx.store, ctx.fetch, pstate.joins); return res.load(mapping, ctx.store, ctx.fetch, pstate.joins);
} }
@ -808,6 +823,8 @@ public class PCPath
// consume keyProjection // consume keyProjection
PersistenceCapable pc = (PersistenceCapable) res.load(_candidate, PersistenceCapable pc = (PersistenceCapable) res.load(_candidate,
ctx.store, ctx.fetch, pstate.joins); ctx.store, ctx.fetch, pstate.joins);
if (pc == null)
return null;
if (pstate.field.getStrategy() == null || if (pstate.field.getStrategy() == null ||
!(pstate.field.getStrategy() instanceof !(pstate.field.getStrategy() instanceof
HandlerRelationMapTableFieldStrategy)) HandlerRelationMapTableFieldStrategy))

View File

@ -110,10 +110,6 @@ public class ElementEmbedValueHandler
public Object toObjectValue(ValueMapping vm, Object val, public Object toObjectValue(ValueMapping vm, Object val,
OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch) OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch)
throws SQLException { throws SQLException {
if (sm == null)
throw new InvalidStateException(_loc.get("cant-project-owned",
vm));
// check null indicator first // check null indicator first
if (_nullIdx != -1) { if (_nullIdx != -1) {
Object nval; Object nval;

View File

@ -427,7 +427,8 @@ public class StateManagerImpl
} }
public boolean isEmbedded() { public boolean isEmbedded() {
return _owner != null; // _owner may not be set if embed object is from query result
return _owner != null || _state instanceof ENonTransState;
} }
public boolean isFlushed() { public boolean isFlushed() {

View File

@ -1084,6 +1084,27 @@ public class TestEmbeddable extends SingleEMFTestCase {
*/ */
public void queryEntityA_Embed_Coll_Embed() { public void queryEntityA_Embed_Coll_Embed() {
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
// test select embed object from element collection
String[] query = {
"select e, e.intVal1, e.embed.intVal2 from " +
" EntityA_Coll_Embed_Embed a " +
" , in (a.embeds) e order by e.intVal3",
"select e, a.id from EntityA_Coll_Embed_Embed a " +
" , in (a.embeds) e order by a.id",
"select e, e.intVal1, e.embed.intVal2 from " +
" EntityA_Coll_Embed_Embed a " +
" , in (a.embeds) e order by e.intVal3",
};
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_Embed);
}
}
em.clear();
EntityTransaction tran = em.getTransaction(); EntityTransaction tran = em.getTransaction();
tran.begin(); tran.begin();
Query q = em.createQuery("select a from EntityA_Embed_Coll_Embed a"); Query q = em.createQuery("select a from EntityA_Embed_Coll_Embed a");