You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/06/26 08:34:35 UTC
svn commit: r788604 - in
/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria:
CriteriaExpressionBuilder.java Joins.java PathImpl.java RootImpl.java
SubqueryImpl.java
Author: faywang
Date: Fri Jun 26 06:34:34 2009
New Revision: 788604
URL: http://svn.apache.org/viewvc?rev=788604&view=rev
Log:
OPENJPA-1143: correlation join 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/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=788604&r1=788603&r2=788604&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 Fri Jun 26 06:34:34 2009
@@ -49,8 +49,7 @@
*/
public class CriteriaExpressionBuilder {
- public QueryExpressions getQueryExpressions(ExpressionFactory factory,
- CriteriaQueryImpl q) {
+ public QueryExpressions getQueryExpressions(ExpressionFactory factory, CriteriaQueryImpl<?> q) {
QueryExpressions exps = new QueryExpressions();
//exps.setContexts(q.getContexts());
@@ -76,8 +75,7 @@
return exps;
}
- protected void evalAccessPaths(QueryExpressions exps,
- ExpressionFactory factory, CriteriaQueryImpl q) {
+ protected void evalAccessPaths(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
Set<ClassMetaData> metas = new HashSet<ClassMetaData>();
Set<Root<?>> roots = q.getRoots();
if (roots != null) {
@@ -88,17 +86,14 @@
for (Join<?,?> join : root.getJoins()) {
Class<?> cls = join.getAttribute().getJavaType();
if (join.getAttribute().isAssociation()) {
- ClassMetaData meta = metamodel.repos.
- getMetaData(cls, null, true);
- PersistenceType type = metamodel.
- getPersistenceType(meta);
- if (type == PersistenceType.ENTITY ||
- type == PersistenceType.EMBEDDABLE)
+ ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true);
+ PersistenceType type = metamodel.getPersistenceType(meta);
+ if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE)
metas.add(meta);
}
}
if (root.getFetches() != null) {
- for (Fetch fetch : root.getFetches()) {
+ for (Fetch<?,?> fetch : root.getFetches()) {
metas.add(metamodel.repos.getMetaData(
fetch.getAttribute().getJavaType(),
null, false));
@@ -110,8 +105,7 @@
exps.accessPath = metas.toArray(new ClassMetaData[metas.size()]);
}
- protected void evalOrdering(QueryExpressions exps,
- ExpressionFactory factory, CriteriaQueryImpl q) {
+ protected void evalOrdering(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
List<Order> orders = q.getOrderList();
MetamodelImpl model = q.getMetamodel();
if (orders == null)
@@ -124,7 +118,7 @@
for (int i = 0; i < ordercount; i++) {
OrderImpl order = (OrderImpl)orders.get(i);
//Expression<? extends Comparable> expr = order.getExpression();
- Expression expr = order.getExpression5();
+ Expression<?> expr = order.getExpression5();
exps.ordering[i] = Expressions.toValue(
(ExpressionImpl<?>)expr, factory, model, q);
@@ -134,8 +128,7 @@
}
}
- protected void evalGrouping(QueryExpressions exps,
- ExpressionFactory factory, CriteriaQueryImpl q) {
+ protected void evalGrouping(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
// exps.grouping = null; // Value[]
// exps.groupingClauses = null; // String[]
List<Expression<?>> groups = q.getGroupList();
@@ -155,8 +148,7 @@
: having.toKernelExpression(factory, model, q);
}
- protected void evalDistinct(QueryExpressions exps,
- ExpressionFactory factory, CriteriaQueryImpl q) {
+ protected void evalDistinct(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
Boolean distinct = q.getDistinct();
if (distinct == null) {
exps.distinct = QueryExpressions.DISTINCT_FALSE;
@@ -167,22 +159,33 @@
//exps.distinct &= ~QueryExpressions.DISTINCT_AUTO;
}
- protected void evalFilter(QueryExpressions exps, ExpressionFactory factory,
- CriteriaQueryImpl q) {
+ protected void evalFilter(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
Set<Root<?>> roots = q.getRoots();
MetamodelImpl model = q.getMetamodel();
PredicateImpl where = q.getRestriction();
- q.assertRoot();
+ SubqueryImpl<?> subQuery = q.getDelegator();
org.apache.openjpa.kernel.exps.Expression filter = null;
- for (Root<?> root : roots) {
- if (root.getJoins() != null) {
- for (Join<?, ?> join : root.getJoins()) {
- filter = and(factory, ((ExpressionImpl<?>)join)
- .toKernelExpression(factory, model, q), filter);
+ if (subQuery == null || subQuery.getCorrelatedJoins() == null) {
+ q.assertRoot();
+ for (Root<?> root : roots) {
+ if (root.getJoins() != null) {
+ for (Join<?, ?> join : root.getJoins()) {
+ filter = and(factory, ((ExpressionImpl<?>)join)
+ .toKernelExpression(factory, model, q), filter);
+ }
}
+ ((RootImpl<?>)root).addToContext(factory, model, q);
+ }
+ }
+ if (subQuery != null) {
+ List<Join<?,?>> corrJoins = subQuery.getCorrelatedJoins();
+ if (corrJoins != null) {
+ for (int i = 0; i < corrJoins.size(); i++)
+ filter = and(factory, ((ExpressionImpl<?>)corrJoins.get(i))
+ .toKernelExpression(factory, model, q), filter);
}
- ((RootImpl)root).addToContext(factory, model, q);
}
+
if (where != null) {
filter = and(factory, where.toKernelExpression
(factory, model, q), filter);
@@ -192,8 +195,7 @@
exps.filter = filter;
}
- protected void evalProjections(QueryExpressions exps,
- ExpressionFactory factory, CriteriaQueryImpl q) {
+ protected void evalProjections(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
List<Selection<?>> selections = q.getSelectionList();
MetamodelImpl model = q.getMetamodel();
// TODO: fill in projection clauses
@@ -212,8 +214,8 @@
}
private void getProjections(QueryExpressions exps,
- List<Selection<?>> selections, List projections, List aliases,
- ExpressionFactory factory, CriteriaQueryImpl q, MetamodelImpl model) {
+ List<Selection<?>> selections, List projections, List<String> aliases,
+ ExpressionFactory factory, CriteriaQueryImpl<?> q, MetamodelImpl model) {
for (Selection<?> s : selections) {
List<Selection<?>> sels = ((SelectionImpl)s).getSelections();
if (sels == null) {
@@ -229,14 +231,20 @@
}
}
- protected boolean isDefaultProjection(List<Selection<?>> selections,
- CriteriaQueryImpl q) {
- return selections == null
- || (selections.size() == 1 && selections.get(0) == q.getRoot());
+ protected boolean isDefaultProjection(List<Selection<?>> selections, CriteriaQueryImpl<?> q) {
+ if (selections == null)
+ return true;
+ if (selections.size() != 1)
+ return false;
+ Selection<?> sel = selections.get(0);
+ if (q.getRoots() != null && sel == q.getRoot())
+ return true;
+ if ((sel instanceof PathImpl<?,?>) && ((PathImpl<?,?>)sel)._correlatedPath != null)
+ return true;
+ return false;
}
- protected void evalFetchJoin(QueryExpressions exps,
- ExpressionFactory factory, CriteriaQueryImpl q) {
+ protected void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
List<String> iPaths = new ArrayList<String>();
List<String> oPaths = new ArrayList<String>();
Set<Root<?>> roots = q.getRoots();
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=788604&r1=788603&r2=788604&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 Fri Jun 26 06:34:34 2009
@@ -18,6 +18,7 @@
*/
package org.apache.openjpa.persistence.criteria;
+import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
@@ -73,6 +74,10 @@
return (FromImpl<?, Z>) _parent;
}
+ public Member<? extends Z, X> getMember() {
+ return (Member<? extends Z, X>) _member;
+ }
+
/**
* Return the metamodel attribute corresponding to the join.
* @return metamodel attribute type corresponding to the join
@@ -111,32 +116,37 @@
SubqueryImpl<?> subquery = c.getDelegator();
PathImpl<?,?> parent = getInnermostParentPath();
org.apache.openjpa.kernel.exps.Expression filter = null;
- PathImpl<?,?> correlatedParent = null;
+ PathImpl<?,?> correlatedParentPath = 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);
- path.get(_member.fmd, false);
- } else {
- path = (org.apache.openjpa.kernel.exps.Path)toValue(factory, model, c);
- }
+ java.util.List<Join<?,?>> corrJoins = 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 (_correlatedPath == null) {
+ 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))) {
+ correlatedParentPath = _parent.getCorrelatedPath();
+ bind = false;
+ } else {
+ path.setMetaData(subQ.getMetaData());
+ path.get(_member.fmd, allowNull);
+ //path.setSchemaAlias(c.getAlias(_parent));
+ }
+ } else if (c.isRegistered(_parent)) {
+ Value var = c.getVariable(_parent);
+ path = factory.newPath(var);
+ path.setMetaData(meta);
+ path.get(_member.fmd, false);
+ } else
+ path = (org.apache.openjpa.kernel.exps.Path)toValue(factory, model, c);
+
+ 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()) {
@@ -146,11 +156,16 @@
}
org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter);
- if (correlatedParent == null) {
+ if (correlatedParentPath == null) {
return expr;
} else {
- org.apache.openjpa.kernel.exps.Path parentPath = (org.apache.openjpa.kernel.exps.Path)
- correlatedParent.toValue(factory, model, c);
+ org.apache.openjpa.kernel.exps.Path parentPath = null;
+ if (corrJoins != null && corrJoins.contains(_parent)) {
+ Value var = getVariableForCorrPath(subquery, correlatedParentPath);
+ parentPath = factory.newPath(var);
+ } else
+ parentPath = (org.apache.openjpa.kernel.exps.Path)
+ correlatedParentPath.toValue(factory, model, c);
parentPath.get(_member.fmd, allowNull);
//parentPath.setSchemaAlias(c.getAlias(correlatedParent));
path.setMetaData(meta);
@@ -159,6 +174,18 @@
return CriteriaExpressionBuilder.and(factory, expr, filter);
}
}
+
+ private Value getVariableForCorrPath(SubqueryImpl<?> subquery, PathImpl<?,?> path) {
+ AbstractQuery<?> parent = subquery.getParent();
+ if (parent instanceof CriteriaQueryImpl) {
+ return ((CriteriaQueryImpl<?>)parent).getVariable(path);
+ }
+ Value var = ((SubqueryImpl<?>)parent).getDelegate().getVariable(path);
+ if (var != null)
+ return var;
+ return getVariableForCorrPath((SubqueryImpl<?>)parent, path);
+ }
+
}
/**
@@ -214,7 +241,6 @@
@Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> c) {
- ClassMetaData meta = getMemberClassMetaData();
org.apache.openjpa.kernel.exps.Path path = null;
SubqueryImpl<?> subquery = c.getDelegator();
PathImpl<?,?> parent = getInnermostParentPath();
@@ -245,34 +271,40 @@
ClassMetaData meta = getMemberClassMetaData();
org.apache.openjpa.kernel.exps.Path path = null;
SubqueryImpl<?> subquery = c.getDelegator();
- PathImpl<?,?> parent = getInnermostParentPath();
org.apache.openjpa.kernel.exps.Expression filter = null;
- PathImpl correlatedParent = null;
+ java.util.List<Join<?,?>> corrJoins = 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);
- path.get(_member.fmd, false);
- } else {
- path = (org.apache.openjpa.kernel.exps.Path)toValue(factory, model, c);
- }
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);
+ PathImpl<?,?> corrJoin = getCorrelatedJoin(this);
+ PathImpl<?,?> corrRoot = getCorrelatedRoot(subquery);
+
+ PathImpl<?,?> correlatedParentPath = null;
+ if (_correlatedPath == null) {
+ if (subquery != null) {
+ corrJoins = subquery.getCorrelatedJoins();
+ org.apache.openjpa.kernel.exps.Subquery subQ = subquery.getSubQ();
+ path = factory.newPath(subQ);
+ if (corrJoin != null || corrRoot != null) {
+ correlatedParentPath = _parent.getCorrelatedPath();
+ bind = false;
+ } else {
+ path.setMetaData(subQ.getMetaData());
+ path.get(_member.fmd, allowNull);
+ //path.setSchemaAlias(c.getAlias(_parent));
+ }
+ } else if (c.isRegistered(_parent)) {
+ Value var = c.getVariable(_parent);
+ path = factory.newPath(var);
+ path.setMetaData(meta);
+ path.get(_member.fmd, false);
+ } else
+ path = (org.apache.openjpa.kernel.exps.Path)toValue(factory, model, c);
+
+ 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()) {
@@ -281,19 +313,36 @@
}
}
org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter);
- if (correlatedParent == null) {
+ if (correlatedParentPath == null) {
return expr;
} else {
- org.apache.openjpa.kernel.exps.Path parentPath = (org.apache.openjpa.kernel.exps.Path)
- correlatedParent.toValue(factory, model, c);
+ org.apache.openjpa.kernel.exps.Path parentPath = null;
+ if (corrJoins != null && corrJoins.contains(_parent)) {
+ Value var = getVariableForCorrPath(subquery, correlatedParentPath);
+ parentPath = factory.newPath(var);
+ } else
+ parentPath = (org.apache.openjpa.kernel.exps.Path)
+ correlatedParentPath.toValue(factory, model, c);
+
parentPath.get(_member.fmd, allowNull);
- //parentPath.setSchemaAlias(c.getAlias(correlatedParent));
+ //parentPath.setSchemaAlias(c.getAlias(correlatedParentPath));
path.setMetaData(meta);
//filter = bindVariableForKeyPath(path, alias, filter);
filter = factory.equal(parentPath, path);
return CriteriaExpressionBuilder.and(factory, expr, filter);
}
}
+
+ private Value getVariableForCorrPath(SubqueryImpl<?> subquery, PathImpl<?,?> path) {
+ AbstractQuery<?> parent = subquery.getParent();
+ if (parent instanceof CriteriaQueryImpl) {
+ return ((CriteriaQueryImpl<?>)parent).getVariable(path);
+ }
+ Value var = ((SubqueryImpl<?>)parent).getDelegate().getVariable(path);
+ if (var != null)
+ return var;
+ return getVariableForCorrPath((SubqueryImpl<?>)parent, path);
+ }
}
/**
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=788604&r1=788603&r2=788604&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 Fri Jun 26 06:34:34 2009
@@ -56,8 +56,8 @@
protected final PathImpl<?,Z> _parent;
protected final Members.Member<? super Z,?> _member;
private boolean isEmbedded = false;
- private PathImpl<?,?> _correlatedParent;
-
+ protected PathImpl<?,?> _correlatedPath;
+
/**
* Protected. use by root path which neither represent a member nor has a
* parent.
@@ -119,12 +119,11 @@
parent._member);
}
- public void setCorrelatedParent(PathImpl<?,?> correlatedParent) {
- _correlatedParent = correlatedParent;
+ public void setCorrelatedPath(PathImpl<?,?> correlatedPath) {
+ _correlatedPath = correlatedPath;
}
-
- public PathImpl<?,?> getCorrelatedParent() {
- return _correlatedParent;
+ public PathImpl<?,?> getCorrelatedPath() {
+ return _correlatedPath;
}
/**
@@ -137,15 +136,15 @@
return q.getValue(this);
org.apache.openjpa.kernel.exps.Path path = null;
SubqueryImpl<?> subquery = q.getDelegator();
- PathImpl<?,?> parent = getInnermostParentPath();
boolean allowNull = _parent == null ? false : _parent instanceof Join
&& ((Join<?,?>)_parent).getJoinType() != JoinType.INNER;
-
+ PathImpl<?,?> corrJoin = getCorrelatedJoin(this);
+ PathImpl<?,?> corrRoot = getCorrelatedRoot(subquery);
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)) {
+ } else if (corrJoin != null || corrRoot != null) {
org.apache.openjpa.kernel.exps.Subquery subQ = subquery.getSubQ();
path = factory.newPath(subQ);
path.setMetaData(subQ.getMetaData());
@@ -166,11 +165,29 @@
return path;
}
+ public PathImpl<?,?> getCorrelatedRoot(SubqueryImpl<?> subquery) {
+ if (subquery == null)
+ return null;
+ PathImpl<?,?> root = getInnermostParentPath();
+ if (subquery.getRoots() != null && subquery.getRoots().contains(this))
+ return root;
+ return null;
+ }
+
+
+ public PathImpl<?,?> getCorrelatedJoin(PathImpl<?,?> path) {
+ if (path._correlatedPath != null)
+ return path._correlatedPath;
+ if (path._parent == null)
+ return null;
+ return getCorrelatedJoin(path._parent);
+ }
+
/**
* Affirms if this receiver occurs in the roots of the given subquery.
*/
public boolean inSubquery(SubqueryImpl<?> subquery) {
- return subquery != null && subquery.getRoots().contains(this);
+ return subquery != null && (subquery.getRoots() == null ? false : subquery.getRoots().contains(this));
}
protected void traversePath(PathImpl<?,?> parent, org.apache.openjpa.kernel.exps.Path path, FieldMetaData fmd) {
@@ -178,7 +195,7 @@
&& ((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 (parent1 == null || parent1.getCorrelatedPath() != null) {
if (fmd != null)
path.get(fmd, allowNull);
return;
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=788604&r1=788603&r2=788604&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 Fri Jun 26 06:34:34 2009
@@ -50,7 +50,7 @@
}
public void addToContext(ExpressionFactory factory, MetamodelImpl model,
- CriteriaQueryImpl q) {
+ CriteriaQueryImpl<?> q) {
String alias = q.getAlias(this);
Value var = factory.newBoundVariable(alias,
AbstractExpressionBuilder.TYPE_OBJECT);
@@ -71,11 +71,13 @@
CriteriaQueryImpl<?> c) {
SubqueryImpl<?> subquery = c.getDelegator();
Path var = null;
+ //String alias = c.getAlias(this);
if (inSubquery(subquery)) {
Subquery subQ = subquery.getSubQ();
var = factory.newPath(subQ);
} else {
var = factory.newPath();
+ //var.setSchemaAlias(alias);
}
var.setMetaData(_entity.meta);
return var;
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=788604&r1=788603&r2=788604&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 Fri Jun 26 06:34:34 2009
@@ -18,6 +18,7 @@
*/
package org.apache.openjpa.persistence.criteria;
+import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -26,6 +27,7 @@
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
+import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Predicate;
@@ -62,6 +64,7 @@
private java.util.Set<Join<?,?>> _joins;
private Expression<T> _select;
private org.apache.openjpa.kernel.exps.Subquery _subq;
+ private List<Join<?,?>> _corrJoins = null;
public SubqueryImpl(Class<T> cls, AbstractQuery<?> parent) {
super(cls);
@@ -176,7 +179,7 @@
public <Y> Root<Y> correlate(Root<Y> root) {
Types.Entity<Y> entity = (Types.Entity<Y>)root.getModel();
RootImpl<Y> corrRoot = new RootImpl<Y>(entity);
- corrRoot.setCorrelatedParent((RootImpl<Y>)root);
+ corrRoot.setCorrelatedPath((RootImpl<Y>)root);
Set<Root<?>> roots = getRoots();
if (roots == null) {
roots = new LinkedHashSet<Root<?>>();
@@ -186,9 +189,54 @@
return corrRoot;
}
+ public List<Join<?,?>> getCorrelatedJoins() {
+ return _corrJoins;
+ }
+
public <X,Y> Join<X,Y> correlate(Join<X,Y> join) {
- _delegate.from(join.getModel().getBindableJavaType());
- return join;
+ Join corrJoin = clone(join);
+ ((PathImpl<?,?>)corrJoin).setCorrelatedPath((PathImpl<?,?>)join);
+ if (_corrJoins == null)
+ _corrJoins = new ArrayList<Join<?,?>>();
+ _corrJoins.add(corrJoin);
+ return corrJoin;
+ }
+
+ private Join<?,?> clone(Join<?,?> join) {
+ List<Members.SingularAttributeImpl<?,?>> members =
+ new ArrayList<Members.SingularAttributeImpl<?,?>>();
+ List<JoinType> jts = new ArrayList<JoinType>();
+ FromImpl<?,?> root = getMembers(join, members, jts);
+ Members.SingularAttributeImpl<?,?> member = members.get(0);
+ JoinType jt = jts.get(0);
+ Join<?,?> join1 = makeJoin(root, member, jt);
+ for (int i = 1; i < members.size(); i++) {
+ join1 = makeJoin((FromImpl<?,?>)join1, members.get(i), jts.get(i));
+ }
+ return join1;
+ }
+
+ private Join<?,?> makeJoin(FromImpl<?,?> parent, Members.SingularAttributeImpl<?,?> member, JoinType jt) {
+ return new Joins.SingularJoin(parent, member, jt);
+ }
+
+ private FromImpl<?,?> getMembers(Join<?,?> join, List<Members.SingularAttributeImpl<?,?>> members,
+ List<JoinType> jts) {
+ PathImpl<?,?> parent = (PathImpl<?,?>)join.getParentPath();
+ Members.SingularAttributeImpl<?,?> member =
+ (Members.SingularAttributeImpl<?,?>)((Joins.SingularJoin<?,?>)join).getMember();
+ JoinType jt = join.getJoinType();
+ FromImpl<?,?> root = null;
+ if (parent instanceof RootImpl<?>) {
+ members.add(member);
+ jts.add(jt);
+ return (FromImpl<?,?>)parent;
+ } else {
+ root = getMembers((Join<?,?>)parent, members, jts);
+ }
+ members.add(member);
+ jts.add(jt);
+ return root;
}
public <X,Y> CollectionJoin<X,Y> correlate(CollectionJoin<X,Y> join) {
_delegate.from(join.getModel().getBindableJavaType());
@@ -225,7 +273,7 @@
public Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
final boolean subclasses = true;
- CriteriaExpressionBuilder queryEval = new CriteriaExpressionBuilder();
+ CriteriaExpressionBuilder exprBuilder = new CriteriaExpressionBuilder();
String alias = q.getAlias(this);
ClassMetaData candidate = getCandidate();
_subq = factory.newSubquery(candidate, subclasses, alias);
@@ -235,7 +283,7 @@
//Context context = new Context(null, _subq, contexts.peek());
//contexts.push(context);
//_delegate.setContexts(contexts);
- QueryExpressions subexp = queryEval.getQueryExpressions(factory,
+ QueryExpressions subexp = exprBuilder.getQueryExpressions(factory,
_delegate);
_subq.setQueryExpressions(subexp);
if (subexp.projections.length > 0)
@@ -248,18 +296,42 @@
// correlated parent, the candidate of the subquery
// should be the class metadata of the collection element
private ClassMetaData getCandidate() {
+ if (_delegate.getRoots() == null && _corrJoins != null) {
+ FromImpl<?,?> corrJoin = (FromImpl<?,?>) _corrJoins.get(0);
+ if (corrJoin.getJoins() != null) {
+ FromImpl<?,?> join = (FromImpl<?,?>)corrJoin.getJoins().iterator().next();
+ return getInnermostCandidate(join);
+ }
+ }
+
RootImpl<?> root = (RootImpl<?>)getRoot();
- PathImpl<?, ?> correlatedRoot = root.getCorrelatedParent();
- if (correlatedRoot != null && root.getJoins() != null) {
- Join<?,?> join = root.getJoins().iterator().next();
- FieldMetaData fmd = ((Members.Member<?, ?>)join.getAttribute()).fmd;
- if (join.getAttribute().isCollection()) {
- return fmd.isElementCollection() ? fmd.getEmbeddedMetaData(): fmd.getElement().getDeclaredTypeMetaData();
- } else {
- return fmd.getDeclaredTypeMetaData();
- }
+ RootImpl<?> corrRoot = (RootImpl<?>)root.getCorrelatedPath();
+ if (corrRoot != null && root.getJoins() != null) {
+ FromImpl<?,?> join = (FromImpl<?,?>) root.getJoins().iterator().next();
+ return getInnermostCandidate(join);
}
+
return ((AbstractManagedType<?>)root.getModel()).meta;
}
+ private ClassMetaData getInnermostCandidate(FromImpl<?,?> from) {
+ if (from.getJoins() != null) {
+ from = (FromImpl<?,?>) from.getJoins().iterator().next();
+ return getInnermostCandidate(from);
+ }
+ return getCandidate(from);
+ }
+
+
+ private ClassMetaData getCandidate(FromImpl<?,?> from) {
+ 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().getDeclaredTypeMetaData();
+ return from._member.fmd.getDeclaredTypeMetaData();
+
+ }
}