Author: faywang
Date: Wed Jun 24 06:02:17 2009
New Revision: 787916
URL: http://svn.apache.org/viewvc?rev=787916&view=rev
Log:
OPENJPA-1143: subquery support
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java?rev=787916&r1=787915&r2=787916&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java
Wed Jun 24 06:02:17 2009
@@ -40,7 +40,6 @@
import org.apache.openjpa.persistence.meta.AbstractManagedType;
import org.apache.openjpa.persistence.meta.Members;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
-import org.apache.openjpa.persistence.meta.Types;
/**
* Converts expressions of a CriteriaQuery to kernel Expression.
@@ -53,6 +52,7 @@
public QueryExpressions getQueryExpressions(ExpressionFactory factory,
CriteriaQueryImpl q) {
QueryExpressions exps = new QueryExpressions();
+ //exps.setContexts(q.getContexts());
evalAccessPaths(exps, factory, q);
//exps.alias = null; // String
@@ -181,10 +181,7 @@
.toKernelExpression(factory, model, q), filter);
}
}
- if (((RootImpl<?>)root).getCorrelatedParent() != null) {
- filter = and(factory, ((RootImpl<?>)root)
- .toKernelExpression(factory, model, q), filter);
- }
+ ((RootImpl)root).addToContext(factory, model, q);
}
if (where != null) {
filter = and(factory, where.toKernelExpression
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java?rev=787916&r1=787915&r2=787916&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java
Wed Jun 24 06:02:17 2009
@@ -20,16 +20,14 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.persistence.Parameter;
+import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Order;
@@ -45,7 +43,6 @@
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.QueryExpressions;
import org.apache.openjpa.kernel.exps.Value;
-import org.apache.openjpa.persistence.QueryImpl;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Types;
@@ -73,7 +70,7 @@
private PredicateImpl _having;
private List<Subquery<?>> _subqueries;
private Boolean _distinct;
- private SubqueryImpl<?> _context;
+ private SubqueryImpl<?> _delegator;
// AliasContext
private int aliasCount = 0;
@@ -83,25 +80,38 @@
new HashMap<Selection<?>, Value>();
private Map<Selection<?>,Value> _values =
new HashMap<Selection<?>, Value>();
- private Map<Selection<?>,String> _aliases =
- new HashMap<Selection<?>, String>();
+ private Map<Selection<?>,String> _aliases = null;
+
+ // SubqueryContext
+ //private Stack<Context> _contexts = null;
public CriteriaQueryImpl(MetamodelImpl model) {
this._model = model;
+ _aliases = new HashMap<Selection<?>, String>();
}
- public void setContext(SubqueryImpl<?> context) {
- _context = context;
+ public CriteriaQueryImpl(MetamodelImpl model, SubqueryImpl<?> delegator) {
+ this._model = model;
+ _delegator = delegator;
+ _aliases = getAliases();
+ }
+
+ public void setDelegator(SubqueryImpl<?> delegator) {
+ _delegator = delegator;
}
- public SubqueryImpl<?> getContext() {
- return _context;
+ public SubqueryImpl<?> getDelegator() {
+ return _delegator;
}
public MetamodelImpl getMetamodel() {
return _model;
}
+ //public Stack<Context> getContexts() {
+ // return _contexts;
+ //}
+
public CriteriaQuery distinct(boolean distinct) {
_distinct = distinct;
return this;
@@ -319,8 +329,11 @@
* receiver with the help of the given {...@link ExpressionFactory}.
*/
QueryExpressions getQueryExpressions(ExpressionFactory factory) {
+ //_contexts = new Stack<Context>();
+ //Context context = new Context(null, null, null);
+ // _contexts.push(context);
return new CriteriaExpressionBuilder()
- .getQueryExpressions(factory, this);
+ .getQueryExpressions(factory, this);
}
public void assertRoot() {
@@ -329,6 +342,30 @@
}
//
+ // SubqueryContext
+ //
+ //public void setContexts(Stack<Context> contexts) {
+ // _contexts = contexts;
+ //}
+
+ public CriteriaQueryImpl getInnermostParent() {
+ if (_delegator == null)
+ return this;
+ AbstractQuery parent = _delegator.getParent();
+ if (parent instanceof CriteriaQueryImpl)
+ return (CriteriaQueryImpl)parent;
+ // parent is a SubqueryImpl
+ return ((SubqueryImpl)parent).getDelegate().getInnermostParent();
+ }
+
+ public Map<Selection<?>,String> getAliases() {
+ CriteriaQueryImpl c = getInnermostParent();
+ if (c._aliases == null)
+ c._aliases = new HashMap<Selection<?>, String>();
+ return c._aliases;
+ }
+
+ //
// AliasContext management
//
@@ -390,6 +427,8 @@
_variables.put(node, var);
_values.put(node, path);
_aliases.put(node, alias);
+ //_contexts.peek().addSchema(alias, var.getMetaData());
+ //_contexts.peek().addVariable(alias, var);
}
public boolean isRegistered(Selection<?> selection) {
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java?rev=787916&r1=787915&r2=787916&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/FromImpl.java
Wed Jun 24 06:02:17 2009
@@ -29,7 +29,6 @@
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.SetJoin;
-import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.MapAttribute;
@@ -39,7 +38,6 @@
import org.apache.openjpa.persistence.meta.AbstractManagedType;
import org.apache.openjpa.persistence.meta.Members;
-import org.apache.openjpa.persistence.meta.Types;
/**
* Represents a bound type, usually an entity that appears in the from clause,
@@ -174,7 +172,7 @@
public <W,Y> CollectionJoin<W, Y> joinCollection(String attr) {
- return (CollectionJoin<W,Y>)join(attr, JoinType.INNER);
+ return (CollectionJoin<W,Y>)join(type.getCollection(attr),
JoinType.INNER);
}
public <W,Y> CollectionJoin<W, Y> joinCollection(String attr, JoinType jt)
{
@@ -182,7 +180,7 @@
}
public <W,Y> ListJoin<W, Y> joinList(String attr) {
- return (ListJoin<W,Y>)join(attr, JoinType.INNER);
+ return (ListJoin<W,Y>)join(type.getList(attr), JoinType.INNER);
}
public <W,Y> ListJoin<W,Y> joinList(String attr, JoinType jt) {
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java?rev=787916&r1=787915&r2=787916&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Joins.java
Wed Jun 24 06:02:17 2009
@@ -58,11 +58,13 @@
public static class SingularJoin<Z,X> extends FromImpl<Z,X>
implements Join<Z,X>{
private final JoinType joinType;
+ private boolean allowNull = false;
public SingularJoin(FromImpl<?,Z> from,
Members.SingularAttributeImpl<? super Z, X> member, JoinType jt) {
super(from, member, member.getJavaType());
joinType = jt;
+ allowNull = joinType != JoinType.INNER;
}
public JoinType getJoinType() {
@@ -85,16 +87,26 @@
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl c) {
+ ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
+ org.apache.openjpa.kernel.exps.Path path = null;
+ SubqueryImpl<?> subquery = c.getDelegator();
+ PathImpl<?,?> parent = getInnermostParentPath();
if (c.isRegistered(this))
return c.getValue(this);
- boolean allowNull = joinType != JoinType.INNER;
- ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
- org.apache.openjpa.kernel.exps.Path path =
- (org.apache.openjpa.kernel.exps.Path)
- _parent.toValue(factory, model, c);
- path.get(_member.fmd, allowNull);
- path.setMetaData(meta);
- path.setImplicitType(meta.getDescribedType());
+ else if (parent.inSubquery(subquery)) {
+ org.apache.openjpa.kernel.exps.Subquery subQ =
+ subquery.getSubQ();
+ path = factory.newPath(subQ);
+ path.setMetaData(subQ.getMetaData());
+ //path.setSchemaAlias(c.getAlias(this));
+ } else {
+ path =
+ (org.apache.openjpa.kernel.exps.Path)
+ _parent.toValue(factory, model, c);
+ path.get(_member.fmd, allowNull);
+ path.setMetaData(meta);
+ path.setImplicitType(meta.getDescribedType());
+ }
return path;
}
@@ -104,7 +116,23 @@
CriteriaQueryImpl c) {
ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
org.apache.openjpa.kernel.exps.Path path = null;
- if (c.isRegistered(_parent)) {
+ SubqueryImpl<?> subquery = c.getDelegator();
+ PathImpl<?,?> parent = getInnermostParentPath();
+ org.apache.openjpa.kernel.exps.Expression filter = null;
+ PathImpl correlatedParent = null;
+ boolean bind = true;
+ if (parent.inSubquery(subquery)) {
+ org.apache.openjpa.kernel.exps.Subquery subQ =
+ subquery.getSubQ();
+ path = factory.newPath(subQ);
+ correlatedParent = _parent.getCorrelatedParent();
+ if (correlatedParent == null) {
+ path.setMetaData(subQ.getMetaData());
+ path.get(_member.fmd, allowNull);
+ //path.setSchemaAlias(c.getAlias(_parent));
+ } else
+ bind = false;
+ } else if (c.isRegistered(_parent)) {
Value var = c.getVariable(_parent);
path = factory.newPath(var);
path.setMetaData(meta);
@@ -112,12 +140,13 @@
} else
path =
(org.apache.openjpa.kernel.exps.Path)toValue(factory, model,
c);
- Value var = factory.newBoundVariable(c.getAlias(this),
- meta.getDescribedType());
- org.apache.openjpa.kernel.exps.Expression join = factory
- .bindVariable(var, path);
- c.registerVariable(this, var, path);
- org.apache.openjpa.kernel.exps.Expression filter = null;
+ org.apache.openjpa.kernel.exps.Expression join = null;
+ if (bind) {
+ Value var = factory.newBoundVariable(c.getAlias(this),
+ meta.getDescribedType());
+ join = factory.bindVariable(var, path);
+ c.registerVariable(this, var, path);
+ }
if (getJoins() != null) {
for (Join<?, ?> join1 : getJoins()) {
filter = CriteriaExpressionBuilder.and(factory,
@@ -125,7 +154,22 @@
toKernelExpression(factory, model, c), filter);
}
}
- return CriteriaExpressionBuilder.and(factory, join, filter);
+ org.apache.openjpa.kernel.exps.Expression expr =
+ CriteriaExpressionBuilder.and(factory, join, filter);
+
+ if (correlatedParent == null)
+ return expr;
+ else {
+ org.apache.openjpa.kernel.exps.Path parentPath =
+ (org.apache.openjpa.kernel.exps.Path)
+ correlatedParent.toValue(factory, model, c);
+ parentPath.get(_member.fmd, allowNull);
+ //parentPath.setSchemaAlias(c.getAlias(correlatedParent));
+ path.setMetaData(meta);
+ //filter = bindVariableForKeyPath(path, alias, filter);
+ filter = factory.equal(parentPath, path);
+ return CriteriaExpressionBuilder.and(factory, expr, filter);
+ }
}
}
@@ -140,11 +184,13 @@
public static abstract class AbstractCollection<Z,C,E> extends
FromImpl<Z,E>
implements PluralJoin<Z, C, E> {
final JoinType joinType;
+ boolean allowNull = false;
public AbstractCollection(FromImpl<?,Z> from,
Members.PluralAttributeImpl<? super Z, C, E> member, JoinType jt) {
super(from, member, member.getBindableJavaType());
joinType = jt;
+ allowNull = joinType != JoinType.INNER;
}
public JoinType getJoinType() {
@@ -167,6 +213,12 @@
public PluralAttribute<? super Z, C, E> getModel() {
return (PluralAttribute<? super Z, C, E>) _member.getType();
}
+
+ public ClassMetaData getMemberClassMetaData() {
+ return _member.fmd.isElementCollection()
+ ? _member.fmd.getEmbeddedMetaData()
+ : _member.fmd.getElement().getDeclaredTypeMetaData();
+ }
/**
* Convert this path to a kernel path (value).
@@ -174,13 +226,20 @@
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl c) {
- boolean allowNull = joinType != JoinType.INNER;
- ClassMetaData meta = _member.fmd.getElement()
- .getDeclaredTypeMetaData();
+ ClassMetaData meta = getMemberClassMetaData();
org.apache.openjpa.kernel.exps.Path path = null;
+ SubqueryImpl<?> subquery = c.getDelegator();
+ PathImpl<?,?> parent = getInnermostParentPath();
+
if (c.isRegistered(this)) {
Value var = c.getVariable(this);
path = factory.newPath(var);
+ } else if (parent.inSubquery(subquery)) {
+ org.apache.openjpa.kernel.exps.Subquery subQ =
+ subquery.getSubQ();
+ path = factory.newPath(subQ);
+ path.setMetaData(subQ.getMetaData());
+ //path.setSchemaAlias(c.getAlias(this));
} else {
path = (org.apache.openjpa.kernel.exps.Path)
_parent.toValue(factory, model, c);
@@ -197,12 +256,25 @@
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl c) {
- ClassMetaData meta = _member.fmd.isElementCollection()
- ? _member.fmd.getEmbeddedMetaData()
- : _member.fmd.getElement().getDeclaredTypeMetaData();
-
+ ClassMetaData meta = getMemberClassMetaData();
org.apache.openjpa.kernel.exps.Path path = null;
- if (c.isRegistered(_parent)) {
+ SubqueryImpl<?> subquery = c.getDelegator();
+ PathImpl<?,?> parent = getInnermostParentPath();
+ org.apache.openjpa.kernel.exps.Expression filter = null;
+ PathImpl correlatedParent = null;
+ boolean bind = true;
+ if (parent.inSubquery(subquery)) {
+ org.apache.openjpa.kernel.exps.Subquery subQ =
+ subquery.getSubQ();
+ path = factory.newPath(subQ);
+ correlatedParent = _parent.getCorrelatedParent();
+ if (correlatedParent == null) {
+ path.setMetaData(subQ.getMetaData());
+ path.get(_member.fmd, allowNull);
+ //path.setSchemaAlias(c.getAlias(_parent));
+ } else
+ bind = false;
+ } else if (c.isRegistered(_parent)) {
Value var = c.getVariable(_parent);
path = factory.newPath(var);
path.setMetaData(meta);
@@ -210,13 +282,14 @@
} else
path = (org.apache.openjpa.kernel.exps.Path)
toValue(factory, model, c);
-
- Value var = factory.newBoundVariable(c.getAlias(this),
- meta.getDescribedType());
- org.apache.openjpa.kernel.exps.Expression join =
- factory.bindVariable(var, path);
- c.registerVariable(this, var, path);
- org.apache.openjpa.kernel.exps.Expression filter = null;
+
+ org.apache.openjpa.kernel.exps.Expression join = null;
+ if (bind) {
+ Value var = factory.newBoundVariable(c.getAlias(this),
+ meta.getDescribedType());
+ join = factory.bindVariable(var, path);
+ c.registerVariable(this, var, path);
+ }
if (getJoins() != null) {
for (Join<?, ?> join1 : getJoins()) {
filter = CriteriaExpressionBuilder.and(factory,
@@ -224,8 +297,22 @@
toKernelExpression(factory, model, c), filter);
}
}
- return CriteriaExpressionBuilder.and(factory, join, filter);
- }
+ org.apache.openjpa.kernel.exps.Expression expr =
+ CriteriaExpressionBuilder.and(factory, join, filter);
+ if (correlatedParent == null)
+ return expr;
+ else {
+ org.apache.openjpa.kernel.exps.Path parentPath =
+ (org.apache.openjpa.kernel.exps.Path)
+ correlatedParent.toValue(factory, model, c);
+ parentPath.get(_member.fmd, allowNull);
+ //parentPath.setSchemaAlias(c.getAlias(correlatedParent));
+ path.setMetaData(meta);
+ //filter = bindVariableForKeyPath(path, alias, filter);
+ filter = factory.equal(parentPath, path);
+ return CriteriaExpressionBuilder.and(factory, expr, filter);
+ }
+ }
}
/**
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java?rev=787916&r1=787915&r2=787916&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java
Wed Jun 24 06:02:17 2009
@@ -23,7 +23,6 @@
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Path;
-import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MapAttribute;
@@ -58,7 +57,8 @@
protected final PathImpl<?,Z> _parent;
protected final Members.Member<? super Z,?> _member;
private boolean isEmbedded = false;
-
+ private PathImpl<?,?> _correlatedParent;
+
/**
* Protected. use by root path which neither represent a member nor has a
* parent.
@@ -121,6 +121,13 @@
parent._member);
}
+ public void setCorrelatedParent(PathImpl<?,?> correlatedParent) {
+ _correlatedParent = correlatedParent;
+ }
+
+ public PathImpl<?,?> getCorrelatedParent() {
+ return _correlatedParent;
+ }
/**
* Convert this path to a kernel path.
@@ -131,27 +138,26 @@
if (q.isRegistered(this))
return q.getValue(this);
org.apache.openjpa.kernel.exps.Path path = null;
- SubqueryImpl<?> subquery = q.getContext();
+ SubqueryImpl<?> subquery = q.getDelegator();
PathImpl<?,?> parent = getInnermostParentPath();
- if (parent.inSubquery(subquery)) {
+ boolean allowNull = _parent == null ? false : _parent instanceof Join
+ && ((Join<?,?>)_parent).getJoinType() != JoinType.INNER;
+
+ if (_parent != null && q.isRegistered(_parent)) {
+ path = factory.newPath(q.getVariable(_parent));
+ //path.setSchemaAlias(q.getAlias(_parent));
+ path.get(_member.fmd, allowNull);
+ } else if (parent.inSubquery(subquery)) {
org.apache.openjpa.kernel.exps.Subquery subQ = subquery.getSubQ();
path = factory.newPath(subQ);
path.setMetaData(subQ.getMetaData());
- boolean allowNull = false;
+ //path.setSchemaAlias(q.getAlias(_parent));
+ traversePath(_parent, path, _member.fmd);
+ } else if (_parent != null) {
+ path = (org.apache.openjpa.kernel.exps.Path)
+ _parent.toValue(factory, model, q);
path.get(_member.fmd, allowNull);
- } else if (_parent != null) {
- if (q.isRegistered(_parent)) {
- path = factory.newPath(q.getVariable(_parent));
- ClassMetaData meta = _member.fmd.getDeclaredTypeMetaData();
- path.setMetaData(meta);
- } else {
- path = (org.apache.openjpa.kernel.exps.Path)
- _parent.toValue(factory, model, q);
- }
- boolean allowNull = _parent instanceof Join
- && ((Join<?,?>)_parent).getJoinType() != JoinType.INNER;
- path.get(_member.fmd, allowNull);
- } else {
+ } else if (_parent == null) {
path = factory.newPath();
path.setMetaData(model.repos.getCachedMetaData(getJavaType()));
}
@@ -171,6 +177,22 @@
return subquery != null && subquery.getRoots().contains(this);
}
+ protected void traversePath(PathImpl<?,?> parent,
+ org.apache.openjpa.kernel.exps.Path path, FieldMetaData fmd) {
+ boolean allowNull = parent == null ? false : parent instanceof Join
+ && ((Join<?,?>)parent).getJoinType() != JoinType.INNER;
+ FieldMetaData fmd1 = parent._member == null ? null :
parent._member.fmd;
+ PathImpl<?,?> parent1 = parent._parent;
+ if (parent1 == null || parent1.getCorrelatedParent() != null) {
+ if (fmd != null)
+ path.get(fmd, allowNull);
+ return;
+ }
+ traversePath(parent1, path, fmd1);
+ if (fmd != null)
+ path.get(fmd, allowNull);
+ }
+
/**
* Return the path corresponding to the referenced
* single-valued attribute.
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java?rev=787916&r1=787915&r2=787916&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/RootImpl.java
Wed Jun 24 06:02:17 2009
@@ -22,7 +22,7 @@
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.EntityType;
-import org.apache.openjpa.kernel.exps.Expression;
+import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Path;
import org.apache.openjpa.kernel.exps.Subquery;
@@ -39,7 +39,6 @@
*/
public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
private final Types.Entity<X> _entity;
- private RootImpl<X> _correlatedParent;
public RootImpl(Types.Entity<X> type) {
super(type);
@@ -50,12 +49,18 @@
return _entity;
}
- public void setCorrelatedParent(RootImpl<X> correlatedParent) {
- _correlatedParent = correlatedParent;
- }
-
- public RootImpl<X> getCorrelatedParent() {
- return _correlatedParent;
+ public void addToContext(ExpressionFactory factory, MetamodelImpl model,
+ CriteriaQueryImpl q) {
+ String alias = q.getAlias(this);
+ Value var = factory.newBoundVariable(alias,
+ AbstractExpressionBuilder.TYPE_OBJECT);
+ var.setMetaData(_entity.meta);
+ //TODO:
+ //Context currContext = (Context)q.getContexts().peek();
+ //currContext.addSchema(alias, _entity.meta);
+ //currContext.addVariable(alias, var);
+ //if (currContext.schemaAlias == null)
+ // currContext.schemaAlias = alias;
}
/**
@@ -64,7 +69,7 @@
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl c) {
- SubqueryImpl<?> subquery = c.getContext();
+ SubqueryImpl<?> subquery = c.getDelegator();
Path var = null;
if (inSubquery(subquery)) {
Subquery subQ = subquery.getSubQ();
@@ -85,13 +90,8 @@
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl c) {
Value path = toValue(factory, model, c);
Value var = factory.newBoundVariable(c.getAlias(this),
- _entity.meta.getDescribedType());
- Expression exp = factory.bindVariable(var, path);
-
- if (_correlatedParent == null)
- return exp;
- Value path1 = _correlatedParent.toValue(factory, model, c);
- return factory.equal(path1, path);
+ _entity.meta.getDescribedType());
+ return factory.bindVariable(var, path);
}
public String toString() {
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java?rev=787916&r1=787915&r2=787916&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java
Wed Jun 24 06:02:17 2009
@@ -39,6 +39,7 @@
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.persistence.meta.AbstractManagedType;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Types;
@@ -53,23 +54,47 @@
* @param <T> the type selected by this subquery.
*/
public class SubqueryImpl<T> extends ExpressionImpl<T> implements Subquery<T> {
- private final CriteriaQueryImpl _parent;
+ private final AbstractQuery _parent;
private final CriteriaQueryImpl _delegate;
+ private final MetamodelImpl _model;
private java.util.Set<Join<?,?>> _joins;
private Expression<T> _select;
private org.apache.openjpa.kernel.exps.Subquery _subq;
- public SubqueryImpl(Class<T> cls, CriteriaQueryImpl parent) {
+ public SubqueryImpl(Class<T> cls, AbstractQuery parent) {
super(cls);
_parent = parent;
- _delegate = new CriteriaQueryImpl(parent.getMetamodel());
- _delegate.setContext(this);
+ if (parent instanceof CriteriaQueryImpl)
+ _model = ((CriteriaQueryImpl)parent).getMetamodel();
+ else if (parent instanceof SubqueryImpl)
+ _model = ((SubqueryImpl)parent).getMetamodel();
+ else
+ _model = null;
+
+ _delegate = new CriteriaQueryImpl(_model, this);
}
public AbstractQuery getParent() {
return _parent;
}
+ public CriteriaQueryImpl getDelegate() {
+ return _delegate;
+ }
+
+ public MetamodelImpl getMetamodel() {
+ return _model;
+ }
+
+ //public Stack<Context> getContexts() {
+ // return getInnermostParent().getContexts();
+ //}
+
+ public CriteriaQueryImpl getInnermostParent() {
+ return (CriteriaQueryImpl)(((_parent instanceof CriteriaQueryImpl)) ?
+ _parent : ((SubqueryImpl)_parent).getInnermostParent());
+ }
+
public Subquery<T> select(Expression<T> expression) {
_select = expression;
_delegate.select(expression);
@@ -201,15 +226,41 @@
final boolean subclasses = true;
CriteriaExpressionBuilder queryEval = new CriteriaExpressionBuilder();
String alias = q.getAlias(this);
- ClassMetaData candidate =
- ((AbstractManagedType<?>)getRoot().getModel()).meta;
+ ClassMetaData candidate = getCandidate();
_subq = factory.newSubquery(candidate, subclasses, alias);
_subq.setMetaData(candidate);
+ //TODO:
+ //Stack<Context> contexts = getContexts();
+ //Context context = new Context(null, _subq, contexts.peek());
+ //contexts.push(context);
+ //_delegate.setContexts(contexts);
QueryExpressions subexp = queryEval.getQueryExpressions(factory,
_delegate);
_subq.setQueryExpressions(subexp);
if (subexp.projections.length > 0)
JPQLExpressionBuilder.checkEmbeddable(subexp.projections[0], null);
+ //contexts.pop();
return _subq;
}
+
+ // if we are in a subquery against a collection from a
+ // correlated parent, the candidate of the subquery
+ // should be the class metadata of the collection element
+ private ClassMetaData getCandidate() {
+ RootImpl<?> root = (RootImpl<?>)getRoot();
+ RootImpl<?> correlatedRoot = (RootImpl<?>)root.getCorrelatedParent();
+ if (correlatedRoot != null && root.getJoins() != null) {
+ FromImpl join = (FromImpl) root.getJoins().iterator().next();
+ if (join._member.fmd.getDeclaredTypeCode() ==
+ JavaTypes.COLLECTION ||
+ join._member.fmd.getDeclaredTypeCode() ==
+ JavaTypes.MAP)
+ return join._member.fmd.isElementCollection()
+ ? join._member.fmd.getEmbeddedMetaData()
+ : join._member.fmd.getElement().getDeclaredTypeMetaData();
+ return join._member.fmd.getDeclaredTypeMetaData();
+ }
+ return ((AbstractManagedType<?>)root.getModel()).meta;
+ }
+
}