mirror of https://github.com/apache/openjpa.git
OPENJPA-1143: embeddable support for Criteria API
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@798026 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b8610366f0
commit
62a32c5596
|
@ -35,9 +35,11 @@ import javax.persistence.metamodel.MapAttribute;
|
|||
import javax.persistence.metamodel.PluralAttribute;
|
||||
import javax.persistence.metamodel.SetAttribute;
|
||||
|
||||
import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
|
||||
import org.apache.openjpa.kernel.exps.ExpressionFactory;
|
||||
import org.apache.openjpa.kernel.exps.Value;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
import org.apache.openjpa.meta.FieldMetaData;
|
||||
import org.apache.openjpa.persistence.meta.Members;
|
||||
import org.apache.openjpa.persistence.meta.MetamodelImpl;
|
||||
import org.apache.openjpa.persistence.meta.Members.Member;
|
||||
|
@ -100,6 +102,7 @@ public abstract class Joins {
|
|||
path = factory.newPath(subQ);
|
||||
path.setMetaData(subQ.getMetaData());
|
||||
path.setSchemaAlias(c.getAlias(this));
|
||||
path.get(_member.fmd, allowNull);
|
||||
} else {
|
||||
path = (org.apache.openjpa.kernel.exps.Path) _parent.toValue(factory, model, c);
|
||||
path.get(_member.fmd, allowNull);
|
||||
|
@ -125,14 +128,19 @@ public abstract class Joins {
|
|||
if (subquery != null) {
|
||||
corrJoins = subquery.getCorrelatedJoins();
|
||||
org.apache.openjpa.kernel.exps.Subquery subQ = subquery.getSubQ();
|
||||
path = factory.newPath(subQ);
|
||||
if ((corrJoins != null && corrJoins.contains(_parent)) ||
|
||||
(corrJoins == null && parent.inSubquery(subquery))) {
|
||||
(corrJoins == null && parent.inSubquery(subquery) && _parent.getCorrelatedPath() != null)) {
|
||||
path = factory.newPath(subQ);
|
||||
correlatedParentPath = _parent.getCorrelatedPath();
|
||||
bind = false;
|
||||
} else {
|
||||
path.setMetaData(subQ.getMetaData());
|
||||
path.get(_member.fmd, allowNull);
|
||||
} else {
|
||||
if (c.isRegistered(_parent)) {
|
||||
Value var = c.getRegisteredVariable(_parent);
|
||||
path = factory.newPath(var);
|
||||
} else
|
||||
path = factory.newPath(subQ);
|
||||
path.setMetaData(meta);
|
||||
path.get(_member.fmd, false);
|
||||
path.setSchemaAlias(c.getAlias(_parent));
|
||||
}
|
||||
} else if (c.isRegistered(_parent)) {
|
||||
|
@ -142,12 +150,19 @@ public abstract class Joins {
|
|||
path.get(_member.fmd, false);
|
||||
} else
|
||||
path = (org.apache.openjpa.kernel.exps.Path)toValue(factory, model, c);
|
||||
|
||||
|
||||
Class<?> type = meta == null ? AbstractExpressionBuilder.TYPE_OBJECT : meta.getDescribedType();
|
||||
Value var = null;
|
||||
if (bind) {
|
||||
Value var = factory.newBoundVariable(c.getAlias(this), meta.getDescribedType());
|
||||
var = factory.newBoundVariable(c.getAlias(this),type);
|
||||
join = factory.bindVariable(var, path);
|
||||
c.registerVariable(this, var, path);
|
||||
}
|
||||
|
||||
if (!_member.fmd.isTypePC()) { // multi-valued relation
|
||||
setImplicitContainsTypes(path, var, AbstractExpressionBuilder.CONTAINS_TYPE_ELEMENT);
|
||||
join = factory.contains(path, var);
|
||||
}
|
||||
}
|
||||
if (getJoins() != null) {
|
||||
for (Join<?, ?> join1 : getJoins()) {
|
||||
|
@ -190,6 +205,39 @@ public abstract class Joins {
|
|||
return getVariableForCorrPath((SubqueryImpl<?>)parent, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the implicit types of the given values based on the fact that
|
||||
* the first is supposed to contain the second.
|
||||
*/
|
||||
public void setImplicitContainsTypes(Value val1, Value val2, int op) {
|
||||
if (val1.getType() == AbstractExpressionBuilder.TYPE_OBJECT) {
|
||||
if (op == AbstractExpressionBuilder.CONTAINS_TYPE_ELEMENT)
|
||||
val1.setImplicitType(Collection.class);
|
||||
else
|
||||
val1.setImplicitType(Map.class);
|
||||
}
|
||||
|
||||
if (val2.getType() == AbstractExpressionBuilder.TYPE_OBJECT && val1 instanceof Path) {
|
||||
FieldMetaData fmd = ((org.apache.openjpa.kernel.exps.Path) val1).last();
|
||||
ClassMetaData meta;
|
||||
if (fmd != null) {
|
||||
if (op == AbstractExpressionBuilder.CONTAINS_TYPE_ELEMENT ||
|
||||
op == AbstractExpressionBuilder.CONTAINS_TYPE_VALUE) {
|
||||
val2.setImplicitType(fmd.getElement().getDeclaredType());
|
||||
meta = fmd.getElement().getDeclaredTypeMetaData();
|
||||
if (meta != null) {
|
||||
val2.setMetaData(meta);
|
||||
}
|
||||
} else {
|
||||
val2.setImplicitType(fmd.getKey().getDeclaredType());
|
||||
meta = fmd.getKey().getDeclaredTypeMetaData();
|
||||
if (meta != null) {
|
||||
val2.setMetaData(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -235,7 +283,7 @@ public abstract class Joins {
|
|||
|
||||
public ClassMetaData getMemberClassMetaData() {
|
||||
return _member.fmd.isElementCollection()
|
||||
? _member.fmd.getEmbeddedMetaData()
|
||||
? _member.fmd.getElement().getEmbeddedMetaData()
|
||||
: _member.fmd.getElement().getDeclaredTypeMetaData();
|
||||
}
|
||||
|
||||
|
@ -288,12 +336,18 @@ public abstract class Joins {
|
|||
corrJoins = subquery.getCorrelatedJoins();
|
||||
org.apache.openjpa.kernel.exps.Subquery subQ = subquery.getSubQ();
|
||||
path = factory.newPath(subQ);
|
||||
if (corrJoin != null || corrRoot != null) {
|
||||
if ((corrJoin != null || corrRoot != null) && _parent.getCorrelatedPath() != null) {
|
||||
path = factory.newPath(subQ);
|
||||
correlatedParentPath = _parent.getCorrelatedPath();
|
||||
bind = false;
|
||||
} else {
|
||||
path.setMetaData(subQ.getMetaData());
|
||||
path.get(_member.fmd, allowNull);
|
||||
if (c.isRegistered(_parent)) {
|
||||
Value var = c.getRegisteredVariable(_parent);
|
||||
path = factory.newPath(var);
|
||||
} else
|
||||
path = factory.newPath(subQ);
|
||||
path.setMetaData(meta);
|
||||
path.get(_member.fmd, false);
|
||||
path.setSchemaAlias(c.getAlias(_parent));
|
||||
}
|
||||
} else if (c.isRegistered(_parent)) {
|
||||
|
@ -304,8 +358,9 @@ public abstract class Joins {
|
|||
} else
|
||||
path = (org.apache.openjpa.kernel.exps.Path)toValue(factory, model, c);
|
||||
|
||||
Class<?> type = meta == null ? AbstractExpressionBuilder.TYPE_OBJECT : meta.getDescribedType();
|
||||
if (bind) {
|
||||
Value var = factory.newBoundVariable(c.getAlias(this), meta.getDescribedType());
|
||||
Value var = factory.newBoundVariable(c.getAlias(this), type);
|
||||
join = factory.bindVariable(var, path);
|
||||
c.registerVariable(this, var, path);
|
||||
}
|
||||
|
@ -477,8 +532,19 @@ public abstract class Joins {
|
|||
*/
|
||||
@Override
|
||||
public Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> c) {
|
||||
org.apache.openjpa.kernel.exps.Path path = factory.newPath(c.getRegisteredVariable(map));
|
||||
return factory.getKey(path);
|
||||
SubqueryImpl<?> subquery = c.getDelegator();
|
||||
PathImpl<?,?> parent = map.getInnermostParentPath();
|
||||
Value val = c.getRegisteredVariable(map);
|
||||
org.apache.openjpa.kernel.exps.Path path = factory.newPath(val);
|
||||
if (parent.inSubquery(subquery)) {
|
||||
org.apache.openjpa.kernel.exps.Subquery subQ = subquery.getSubQ();
|
||||
org.apache.openjpa.kernel.exps.Path var = factory.newPath(subQ);
|
||||
((org.apache.openjpa.kernel.exps.Path)var).setSchemaAlias(c.getAlias(this));
|
||||
var.setMetaData(subQ.getMetaData());
|
||||
return factory.mapKey(path, var);
|
||||
} else {
|
||||
return factory.getKey(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
|
|||
} else {
|
||||
_member = member;
|
||||
}
|
||||
isEmbedded = _member.fmd.isEmbedded();
|
||||
isEmbedded = _member.fmd.isElementCollection() ? _member.fmd.getElement().isEmbedded() :
|
||||
_member.fmd.isEmbedded();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,7 +113,9 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
|
|||
|
||||
protected FieldMetaData getEmbeddedFieldMetaData(FieldMetaData fmd) {
|
||||
Members.Member<?,?> member = getInnermostMember(_parent,_member);
|
||||
ClassMetaData embeddedMeta = member.fmd.getEmbeddedMetaData();
|
||||
ClassMetaData embeddedMeta = member.fmd.isElementCollection() ?
|
||||
member.fmd.getElement().getEmbeddedMetaData() :
|
||||
member.fmd.getEmbeddedMetaData();
|
||||
if (embeddedMeta != null)
|
||||
return embeddedMeta.getField(fmd.getName());
|
||||
else
|
||||
|
|
|
@ -33,7 +33,6 @@ import javax.persistence.criteria.ListJoin;
|
|||
import javax.persistence.criteria.MapJoin;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.criteria.Selection;
|
||||
import javax.persistence.criteria.SetJoin;
|
||||
import javax.persistence.criteria.Subquery;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
|
@ -324,12 +323,10 @@ public class SubqueryImpl<T> extends ExpressionImpl<T> implements Subquery<T> {
|
|||
|
||||
|
||||
private ClassMetaData getCandidate(FromImpl<?,?> from) {
|
||||
if (from._member.fmd.getDeclaredTypeCode() ==
|
||||
JavaTypes.COLLECTION ||
|
||||
from._member.fmd.getDeclaredTypeCode() ==
|
||||
JavaTypes.MAP)
|
||||
if (from._member.fmd.getDeclaredTypeCode() == JavaTypes.COLLECTION ||
|
||||
from._member.fmd.getDeclaredTypeCode() == JavaTypes.MAP)
|
||||
return from._member.fmd.isElementCollection()
|
||||
? from._member.fmd.getEmbeddedMetaData()
|
||||
? from._member.fmd.getElement().getEmbeddedMetaData()
|
||||
: from._member.fmd.getElement().getDeclaredTypeMetaData();
|
||||
return from._member.fmd.getDeclaredTypeMetaData();
|
||||
|
||||
|
|
Loading…
Reference in New Issue