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:
Réda Housni Alaoui
2018-04-24 15:46:30 +02:00
committed by Jens Schauder
parent 7eb629f2f4
commit 876669fc54
2 changed files with 7 additions and 3 deletions

View File

@@ -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());

View File

@@ -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);
}