mirror of https://github.com/apache/openjpa.git
OPENJPA-1013: criteria fetch joins
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@785431 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0d8b1dc074
commit
0b0fb31bce
|
@ -167,4 +167,24 @@ public class TestJoinCondition extends CriteriaTest {
|
|||
|
||||
assertEquivalence(cq, jpql);
|
||||
}
|
||||
|
||||
public void testFetchJoin() {
|
||||
String jpql = "select a from A a JOIN FETCH a.b";
|
||||
|
||||
CriteriaQuery cq = cb.create();
|
||||
Root<A> a = cq.from(A.class);
|
||||
a.fetch(A_.b);
|
||||
|
||||
assertEquivalence(cq, jpql);
|
||||
}
|
||||
|
||||
public void testOuterFetchJoin() {
|
||||
String jpql = "select a from A a LEFT JOIN FETCH a.b";
|
||||
|
||||
CriteriaQuery cq = cb.create();
|
||||
Root<A> a = cq.from(A.class);
|
||||
a.fetch(A_.b, JoinType.LEFT);
|
||||
|
||||
assertEquivalence(cq, jpql);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
|
|||
|
||||
@AllowFailure(message="FetchJoin not implemented")
|
||||
public void testFetchJoins() {
|
||||
String jpql = "SELECT d FROM Department LEFT JOIN FETCH d.employees "
|
||||
String jpql = "SELECT d FROM Department d LEFT JOIN FETCH d.employees "
|
||||
+ "WHERE d.deptNo = 1";
|
||||
CriteriaQuery q = cb.create();
|
||||
Root<Department> d = q.from(Department.class);
|
||||
|
|
|
@ -223,7 +223,7 @@ public class TestTypesafeCriteria extends CriteriaTest {
|
|||
|
||||
@AllowFailure(message="FetchJoin not implemented")
|
||||
public void testFetchJoins() {
|
||||
String jpql = "SELECT d FROM Department LEFT JOIN FETCH d.employees "
|
||||
String jpql = "SELECT d FROM Department d LEFT JOIN FETCH d.employees "
|
||||
+ "WHERE d.deptNo = 1";
|
||||
CriteriaQuery q = cb.create();
|
||||
Root<Department> d = q.from(Department.class);
|
||||
|
|
|
@ -25,16 +25,20 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Fetch;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.JoinType;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.criteria.Selection;
|
||||
import javax.persistence.metamodel.Member;
|
||||
import javax.persistence.metamodel.Type.PersistenceType;
|
||||
|
||||
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.meta.ClassMetaData;
|
||||
import org.apache.openjpa.persistence.meta.Members;
|
||||
import org.apache.openjpa.persistence.meta.MetamodelImpl;
|
||||
import org.apache.openjpa.persistence.meta.Types;
|
||||
|
||||
|
@ -93,12 +97,19 @@ public class CriteriaExpressionBuilder {
|
|||
metas.add(meta);
|
||||
}
|
||||
}
|
||||
if (root.getFetches() != null) {
|
||||
for (Fetch fetch : root.getFetches()) {
|
||||
metas.add(metamodel.repos.getMetaData(
|
||||
fetch.getMember().getMemberJavaType(),
|
||||
null, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exps.accessPath = metas.toArray(new ClassMetaData[metas.size()]);
|
||||
}
|
||||
|
||||
|
||||
protected void evalOrdering(QueryExpressions exps,
|
||||
ExpressionFactory factory, CriteriaQueryImpl q) {
|
||||
List<Order> orders = q.getOrderList();
|
||||
|
@ -229,8 +240,28 @@ public class CriteriaExpressionBuilder {
|
|||
|
||||
protected void evalFetchJoin(QueryExpressions exps,
|
||||
ExpressionFactory factory, CriteriaQueryImpl q) {
|
||||
//exps.fetchInnerPaths = null; // String[]
|
||||
//exps.fetchPaths = null; // String[]
|
||||
List<String> iPaths = new ArrayList<String>();
|
||||
List<String> oPaths = new ArrayList<String>();
|
||||
Set<Root<?>> roots = q.getRoots();
|
||||
if (roots == null)
|
||||
return;
|
||||
for (Root root : roots) {
|
||||
Set<Fetch> fetches = root.getFetches();
|
||||
if (fetches == null)
|
||||
continue;
|
||||
for (Fetch<?,?> fetch : fetches) {
|
||||
String fPath = ((Members.Member<?, ?>)fetch.getMember())
|
||||
.fmd.getFullName(false);
|
||||
oPaths.add(fPath);
|
||||
if (fetch.getJoinType() == JoinType.INNER) {
|
||||
iPaths.add(fPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!iPaths.isEmpty())
|
||||
exps.fetchInnerPaths = iPaths.toArray(new String[iPaths.size()]);
|
||||
if (!oPaths.isEmpty())
|
||||
exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]);
|
||||
}
|
||||
|
||||
protected static org.apache.openjpa.kernel.exps.Expression and (
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.criteria;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.criteria.Fetch;
|
||||
import javax.persistence.criteria.FetchParent;
|
||||
import javax.persistence.criteria.JoinType;
|
||||
import javax.persistence.metamodel.AbstractCollection;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
import javax.persistence.metamodel.ManagedType;
|
||||
import javax.persistence.metamodel.Member;
|
||||
|
||||
import org.apache.openjpa.persistence.meta.Members;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Pinaki Poddar
|
||||
*
|
||||
* @param <Z> type of parent
|
||||
* @param <X> type of this
|
||||
*/
|
||||
public class FetchPathImpl<Z,X> extends PathImpl<Z,X> implements Fetch<Z, X> {
|
||||
Set<Fetch<X,?>> _fetches;
|
||||
JoinType joinType;
|
||||
|
||||
|
||||
FetchPathImpl(FetchParent<?,Z> parent, Members.Member<? super Z,X> member) {
|
||||
this(parent, member, JoinType.INNER);
|
||||
}
|
||||
|
||||
FetchPathImpl(FetchParent<?,Z> parent, Members.Member<? super Z,X> member,
|
||||
JoinType type) {
|
||||
super((PathImpl<?,Z>)parent, member, member.getMemberJavaType());
|
||||
this.joinType = type;
|
||||
}
|
||||
|
||||
public JoinType getJoinType() {
|
||||
return joinType;
|
||||
}
|
||||
|
||||
public Member<? extends Z, X> getMember() {
|
||||
return (Member<? extends Z, X>)_member;
|
||||
}
|
||||
|
||||
public FetchParent<?, Z> getParent() {
|
||||
return (FetchParent<?, Z>)_parent;
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(Attribute<? super X, Y> assoc) {
|
||||
return addFetch((Members.Member<? super X,Y>)assoc, JoinType.INNER);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(AbstractCollection<? super X, ?, Y> assoc) {
|
||||
return addFetch((Members.Member<? super X,Y>)assoc, JoinType.INNER);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(String assocName) {
|
||||
return fetch(assocName, JoinType.INNER);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(Attribute<? super X, Y> assoc, JoinType jt) {
|
||||
return addFetch((Members.Member<? super X,Y>)assoc, jt);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(AbstractCollection<? super X, ?, Y> assoc,
|
||||
JoinType jt) {
|
||||
return addFetch((Members.Member<? super X,Y>)assoc, jt);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(String assocName, JoinType jt) {
|
||||
Attribute<? super X, ?> assoc = ((ManagedType<X>)_member.getType())
|
||||
.getAttribute(assocName);
|
||||
return addFetch((Members.Member<? super X,Y>)assoc, jt);
|
||||
}
|
||||
|
||||
public Set<Fetch<X, ?>> getFetches() {
|
||||
return _fetches;
|
||||
}
|
||||
|
||||
private <Y> Fetch<X,Y> addFetch(Members.Member<? super X, Y> member,
|
||||
JoinType jt) {
|
||||
Fetch<X,Y> fetch = new FetchPathImpl(this, member, jt);
|
||||
if (_fetches == null)
|
||||
_fetches = new HashSet<Fetch<X,?>>();
|
||||
_fetches.add(fetch);
|
||||
return fetch;
|
||||
}
|
||||
|
||||
}
|
|
@ -214,33 +214,43 @@ public class FromImpl<Z,X> extends PathImpl<Z,X> implements From<Z,X> {
|
|||
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(Attribute<? super X, Y> assoc, JoinType jt) {
|
||||
throw new AbstractMethodError();
|
||||
return addFetch((Members.Member<? super X, Y>)assoc, jt);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X,Y> fetch(Attribute<? super X, Y> assoc) {
|
||||
throw new AbstractMethodError();
|
||||
return fetch(assoc, JoinType.INNER);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(AbstractCollection<? super X, ?, Y> assoc,
|
||||
JoinType jt) {
|
||||
throw new AbstractMethodError();
|
||||
return addFetch((Members.Member<? super X, Y>)assoc, jt);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X,Y> fetch(AbstractCollection<? super X, ?, Y> assoc) {
|
||||
throw new AbstractMethodError();
|
||||
return fetch(assoc, JoinType.INNER);
|
||||
}
|
||||
|
||||
//String-based:
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(String assocName) {
|
||||
return (Fetch<X, Y>)fetch(type.getAttribute(assocName));
|
||||
return fetch(assocName, JoinType.INNER);
|
||||
}
|
||||
|
||||
public <Y> Fetch<X, Y> fetch(String assocName, JoinType jt) {
|
||||
return (Fetch<X, Y>)fetch(type.getAttribute(assocName), JoinType.INNER);
|
||||
return (Fetch<X, Y>)fetch(type.getAttribute(assocName), jt);
|
||||
}
|
||||
|
||||
public java.util.Set<Fetch<X, ?>> getFetches() {
|
||||
throw new AbstractMethodError();
|
||||
return _fetches;
|
||||
}
|
||||
|
||||
private <Y> Fetch<X,Y> addFetch(Members.Member<? super X, Y> member,
|
||||
JoinType jt) {
|
||||
Fetch<X,Y> fetch = new FetchPathImpl(this, member, jt);
|
||||
if (_fetches == null)
|
||||
_fetches = new HashSet<Fetch<X,?>>();
|
||||
_fetches.add(fetch);
|
||||
return fetch;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue