From 20f68d43a45b0aad724ac1023f6f846c5d88438b Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Thu, 16 Jun 2016 14:29:32 +0100 Subject: [PATCH] HHH-8488 - Fix Join, CollectionJoin, SetJoin, ListJoin, MapJoin CriteriaBuilder#treat SetJoin behaviour --- .../internal/CriteriaBuilderImpl.java | 24 ++++++++++---- .../criteria/internal/FromImplementor.java | 14 +++++--- .../criteria/internal/QueryStructure.java | 12 ++++--- .../path/CollectionAttributeJoin.java | 33 +++++++++++++++++-- .../internal/path/ListAttributeJoin.java | 33 +++++++++++++++++-- .../internal/path/MapAttributeJoin.java | 33 +++++++++++++++++-- .../internal/path/SetAttributeJoin.java | 33 +++++++++++++++++-- .../internal/path/SingularAttributeJoin.java | 32 ++++++++++++++++-- 8 files changed, 187 insertions(+), 27 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/CriteriaBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/CriteriaBuilderImpl.java index 6c0c018898..c18b10f7b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/CriteriaBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/CriteriaBuilderImpl.java @@ -15,6 +15,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiFunction; import javax.persistence.Tuple; import javax.persistence.criteria.CollectionJoin; import javax.persistence.criteria.CompoundSelection; @@ -1109,31 +1110,31 @@ public class CriteriaBuilderImpl implements HibernateCriteriaBuilder, Serializab @Override @SuppressWarnings("unchecked") public Join treat(Join join, Class type) { - return ( (JoinImplementor) join ).treatAs( type ); + return treat( join, type, (j, t) -> ((JoinImplementor) j).treatAs( t ) ); } @Override @SuppressWarnings("unchecked") public CollectionJoin treat(CollectionJoin join, Class type) { - return ( (CollectionJoinImplementor) join ).treatAs( type ); + return treat( join, type, (j, t) -> ((CollectionJoinImplementor) j).treatAs( t ) ); } @Override @SuppressWarnings("unchecked") public SetJoin treat(SetJoin join, Class type) { - return ( (SetJoinImplementor) join ).treatAs( type ); + return treat( join, type, (j, t) -> ((SetJoinImplementor) j).treatAs( t ) ); } @Override @SuppressWarnings("unchecked") public ListJoin treat(ListJoin join, Class type) { - return ( (ListJoinImplementor) join ).treatAs( type ); + return treat( join, type, (j, t) -> ((ListJoinImplementor) join).treatAs( type ) ); } @Override @SuppressWarnings("unchecked") public MapJoin treat(MapJoin join, Class type) { - return ( (MapJoinImplementor) join ).treatAs( type ); + return treat( join, type, (j, t) -> ((MapJoinImplementor) join).treatAs( type ) ); } @Override @@ -1145,10 +1146,9 @@ public class CriteriaBuilderImpl implements HibernateCriteriaBuilder, Serializab @Override @SuppressWarnings("unchecked") public Root treat(Root root, Class type) { - return ( (RootImpl) root ).treatAs( type ); + return ((RootImpl) root).treatAs( type ); } - // subqueries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @Override @@ -1354,4 +1354,14 @@ public class CriteriaBuilderImpl implements HibernateCriteriaBuilder, Serializab public > Predicate isNotMember(Expression eExpression, Expression cExpression) { return isMember(eExpression, cExpression).not(); } + + private K treat( + Join join, + Class type, + BiFunction, Class, K> f) { + final Set> joins = join.getParent().getJoins(); + final K treatAs = f.apply( join, type ); + joins.add(treatAs); + return treatAs; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/FromImplementor.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/FromImplementor.java index ea0e183025..26c580e7dc 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/FromImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/FromImplementor.java @@ -15,11 +15,15 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext; * @author Steve Ebersole */ public interface FromImplementor extends PathImplementor, From { - public void prepareAlias(RenderingContext renderingContext); - public String renderTableExpression(RenderingContext renderingContext); + void prepareAlias(RenderingContext renderingContext); + String renderTableExpression(RenderingContext renderingContext); - public FromImplementor correlateTo(CriteriaSubqueryImpl subquery); - public void prepareCorrelationDelegate(FromImplementor parent); - public FromImplementor getCorrelationParent(); + FromImplementor correlateTo(CriteriaSubqueryImpl subquery); + void prepareCorrelationDelegate(FromImplementor parent); + FromImplementor getCorrelationParent(); + + default boolean shouldBeRendered(){ + return true; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/QueryStructure.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/QueryStructure.java index df54e9c98f..16a097711b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/QueryStructure.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/QueryStructure.java @@ -336,11 +336,13 @@ public class QueryStructure implements Serializable { } for ( Join join : joins ) { - ( (FromImplementor) join ).prepareAlias( renderingContext ); - jpaqlQuery.append( renderJoinType( join.getJoinType() ) ) - .append( ( (FromImplementor) join ).renderTableExpression( renderingContext ) ); - renderJoins( jpaqlQuery, renderingContext, join.getJoins() ); - renderFetches( jpaqlQuery, renderingContext, join.getFetches() ); + if ( ((FromImplementor) join).shouldBeRendered() ) { + ((FromImplementor) join).prepareAlias( renderingContext ); + jpaqlQuery.append( renderJoinType( join.getJoinType() ) ) + .append( ((FromImplementor) join).renderTableExpression( renderingContext ) ); + renderJoins( jpaqlQuery, renderingContext, join.getJoins() ); + renderFetches( jpaqlQuery, renderingContext, join.getFetches() ); + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/CollectionAttributeJoin.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/CollectionAttributeJoin.java index b1d4c36a65..b813f6c53c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/CollectionAttributeJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/CollectionAttributeJoin.java @@ -12,6 +12,7 @@ import javax.persistence.criteria.Expression; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Predicate; import javax.persistence.metamodel.CollectionAttribute; +import javax.persistence.metamodel.ManagedType; import org.hibernate.query.criteria.internal.CollectionJoinImplementor; import org.hibernate.query.criteria.internal.CriteriaBuilderImpl; @@ -97,12 +98,35 @@ public class CollectionAttributeJoin @Override public String getAlias() { - return original.getAlias(); + return isCorrelated() ? getCorrelationParent().getAlias() : super.getAlias(); } @Override public void prepareAlias(RenderingContext renderingContext) { - // do nothing... + if ( getAlias() == null ) { + if ( isCorrelated() ) { + setAlias( getCorrelationParent().getAlias() ); + } + else { + setAlias( renderingContext.generateAlias() ); + } + } + } + + @Override + protected void setAlias(String alias) { + super.setAlias( alias ); + original.setAlias( alias ); + } + + @Override + public boolean shouldBeRendered() { + if ( getJoins().size() > 0 ) { + return true; + } + else { + return false; + } } @Override @@ -110,6 +134,11 @@ public class CollectionAttributeJoin return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")"; } + @Override + protected ManagedType locateManagedType() { + return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType ); + } + @Override public String getPathIdentifier() { return "treat(" + getAlias() + " as " + treatAsType.getName() + ")"; diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/ListAttributeJoin.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/ListAttributeJoin.java index 68b44208b9..8ed333dbb0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/ListAttributeJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/ListAttributeJoin.java @@ -12,6 +12,7 @@ import javax.persistence.criteria.Expression; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Predicate; import javax.persistence.metamodel.ListAttribute; +import javax.persistence.metamodel.ManagedType; import org.hibernate.query.criteria.internal.CriteriaBuilderImpl; import org.hibernate.query.criteria.internal.CriteriaSubqueryImpl; @@ -105,12 +106,35 @@ public class ListAttributeJoin @Override public String getAlias() { - return original.getAlias(); + return isCorrelated() ? getCorrelationParent().getAlias() : super.getAlias(); } @Override public void prepareAlias(RenderingContext renderingContext) { - // do nothing... + if ( getAlias() == null ) { + if ( isCorrelated() ) { + setAlias( getCorrelationParent().getAlias() ); + } + else { + setAlias( renderingContext.generateAlias() ); + } + } + } + + @Override + protected void setAlias(String alias) { + super.setAlias( alias ); + original.setAlias( alias ); + } + + @Override + public boolean shouldBeRendered() { + if ( getJoins().size() > 0 ) { + return true; + } + else { + return false; + } } @Override @@ -118,6 +142,11 @@ public class ListAttributeJoin return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")"; } + @Override + protected ManagedType locateManagedType() { + return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType ); + } + @Override public String getPathIdentifier() { return "treat(" + getAlias() + " as " + treatAsType.getName() + ")"; diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/MapAttributeJoin.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/MapAttributeJoin.java index 0f16fee902..2d4ff7c59a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/MapAttributeJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/MapAttributeJoin.java @@ -12,6 +12,7 @@ import javax.persistence.criteria.Expression; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; +import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.MapAttribute; import org.hibernate.query.criteria.internal.CriteriaBuilderImpl; @@ -126,12 +127,35 @@ public class MapAttributeJoin @Override public String getAlias() { - return original.getAlias(); + return isCorrelated() ? getCorrelationParent().getAlias() : super.getAlias(); } @Override public void prepareAlias(RenderingContext renderingContext) { - // do nothing... + if ( getAlias() == null ) { + if ( isCorrelated() ) { + setAlias( getCorrelationParent().getAlias() ); + } + else { + setAlias( renderingContext.generateAlias() ); + } + } + } + + @Override + protected void setAlias(String alias) { + super.setAlias( alias ); + original.setAlias( alias ); + } + + @Override + public boolean shouldBeRendered() { + if ( getJoins().size() > 0 ) { + return true; + } + else { + return false; + } } @Override @@ -139,6 +163,11 @@ public class MapAttributeJoin return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")"; } + @Override + protected ManagedType locateManagedType() { + return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType ); + } + @Override public String getPathIdentifier() { return "treat(" + getAlias() + " as " + treatAsType.getName() + ")"; diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SetAttributeJoin.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SetAttributeJoin.java index 57c03ad9e3..04fcaa729a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SetAttributeJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SetAttributeJoin.java @@ -11,6 +11,7 @@ import java.util.Set; import javax.persistence.criteria.Expression; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Predicate; +import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.SetAttribute; import org.hibernate.query.criteria.internal.CriteriaBuilderImpl; @@ -102,12 +103,35 @@ public class SetAttributeJoin @Override public String getAlias() { - return original.getAlias(); + return isCorrelated() ? getCorrelationParent().getAlias() : super.getAlias(); } @Override public void prepareAlias(RenderingContext renderingContext) { - // do nothing... + if ( getAlias() == null ) { + if ( isCorrelated() ) { + setAlias( getCorrelationParent().getAlias() ); + } + else { + setAlias( renderingContext.generateAlias() ); + } + } + } + + @Override + protected void setAlias(String alias) { + super.setAlias( alias ); + original.setAlias( alias ); + } + + @Override + public boolean shouldBeRendered() { + if ( getJoins().size() > 0 ) { + return true; + } + else { + return false; + } } @Override @@ -115,6 +139,11 @@ public class SetAttributeJoin return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")"; } + @Override + protected ManagedType locateManagedType() { + return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType ); + } + @Override public String getPathIdentifier() { return "treat(" + getAlias() + " as " + treatAsType.getName() + ")"; diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SingularAttributeJoin.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SingularAttributeJoin.java index 29e2a386fa..8de9bd69d3 100755 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SingularAttributeJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/path/SingularAttributeJoin.java @@ -133,12 +133,40 @@ public class SingularAttributeJoin extends AbstractJoinImpl { @Override public String getAlias() { - return original.getAlias(); + return isCorrelated() ? getCorrelationParent().getAlias() : super.getAlias(); } @Override public void prepareAlias(RenderingContext renderingContext) { - // do nothing... + if ( getAlias() == null ) { + if ( isCorrelated() ) { + setAlias( getCorrelationParent().getAlias() ); + } + else { + setAlias( renderingContext.generateAlias() ); + } + } + } + + @Override + protected void setAlias(String alias) { + super.setAlias( alias ); + original.setAlias( alias ); + } + + @Override + protected ManagedType locateManagedType() { + return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType ); + } + + @Override + public boolean shouldBeRendered() { + if ( getJoins().size() > 0 ) { + return true; + } + else { + return false; + } } @Override