DATAJPA-1238 - Avoid outer join when entity valued attribute is queried.
This avoids an extra join for derived queries that use a single valued entity in a where clause. If this actually reduces the number of joins used in the SQL statement still depends on the JPA implementation. Original pull request: #270.
This commit is contained in:
committed by
Jens Schauder
parent
7eb629f2f4
commit
876669fc54
@@ -588,7 +588,7 @@ public abstract class QueryUtils {
|
||||
propertyPathModel = from.get(segment).getModel();
|
||||
}
|
||||
|
||||
if (requiresJoin(propertyPathModel, model instanceof PluralAttribute) && !isAlreadyFetched(from, segment)) {
|
||||
if (requiresJoin(propertyPathModel, model instanceof PluralAttribute, !property.hasNext()) && !isAlreadyFetched(from, segment)) {
|
||||
Join<?, ?> join = getOrCreateJoin(from, segment);
|
||||
return (Expression<T>) (property.hasNext() ? toExpressionRecursively(join, property.next()) : join);
|
||||
} else {
|
||||
@@ -603,9 +603,10 @@ public abstract class QueryUtils {
|
||||
*
|
||||
* @param propertyPathModel may be {@literal null}.
|
||||
* @param forPluralAttribute
|
||||
* @param forLeafProperty
|
||||
* @return
|
||||
*/
|
||||
private static boolean requiresJoin(@Nullable Bindable<?> propertyPathModel, boolean forPluralAttribute) {
|
||||
private static boolean requiresJoin(@Nullable Bindable<?> propertyPathModel, boolean forPluralAttribute, boolean forLeafProperty) {
|
||||
|
||||
if (propertyPathModel == null && forPluralAttribute) {
|
||||
return true;
|
||||
@@ -620,6 +621,9 @@ public abstract class QueryUtils {
|
||||
if (!ASSOCIATION_TYPES.containsKey(attribute.getPersistentAttributeType())) {
|
||||
return false;
|
||||
}
|
||||
if (forLeafProperty && !attribute.isCollection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Class<? extends Annotation> associationAnnotation = ASSOCIATION_TYPES.get(attribute.getPersistentAttributeType());
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class QueryUtilsIntegrationTests {
|
||||
CriteriaQuery<User> query = builder.createQuery(User.class);
|
||||
Root<User> root = query.from(User.class);
|
||||
|
||||
QueryUtils.toExpressionRecursively(root, PropertyPath.from("manager", User.class));
|
||||
QueryUtils.toExpressionRecursively(root, PropertyPath.from("manager.firstname", User.class));
|
||||
|
||||
assertThat(root.getJoins()).hasSize(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user