HHH-8488 - Fix Join, CollectionJoin, SetJoin, ListJoin, MapJoin CriteriaBuilder#treat SetJoin behaviour

This commit is contained in:
Andrea Boriero 2016-06-16 14:29:32 +01:00
parent 9d20d3ab03
commit 20f68d43a4
8 changed files with 187 additions and 27 deletions

View File

@ -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 <X, T, V extends T> Join<X, V> treat(Join<X, T> join, Class<V> type) {
return ( (JoinImplementor) join ).treatAs( type );
return treat( join, type, (j, t) -> ((JoinImplementor) j).treatAs( t ) );
}
@Override
@SuppressWarnings("unchecked")
public <X, T, E extends T> CollectionJoin<X, E> treat(CollectionJoin<X, T> join, Class<E> type) {
return ( (CollectionJoinImplementor) join ).treatAs( type );
return treat( join, type, (j, t) -> ((CollectionJoinImplementor) j).treatAs( t ) );
}
@Override
@SuppressWarnings("unchecked")
public <X, T, E extends T> SetJoin<X, E> treat(SetJoin<X, T> join, Class<E> type) {
return ( (SetJoinImplementor) join ).treatAs( type );
return treat( join, type, (j, t) -> ((SetJoinImplementor) j).treatAs( t ) );
}
@Override
@SuppressWarnings("unchecked")
public <X, T, E extends T> ListJoin<X, E> treat(ListJoin<X, T> join, Class<E> type) {
return ( (ListJoinImplementor) join ).treatAs( type );
return treat( join, type, (j, t) -> ((ListJoinImplementor) join).treatAs( type ) );
}
@Override
@SuppressWarnings("unchecked")
public <X, K, T, V extends T> MapJoin<X, K, V> treat(MapJoin<X, K, T> join, Class<V> 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 <X, T extends X> Root<T> treat(Root<X> root, Class<T> type) {
return ( (RootImpl) root ).treatAs( type );
return ((RootImpl) root).treatAs( type );
}
// subqueries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
@ -1354,4 +1354,14 @@ public class CriteriaBuilderImpl implements HibernateCriteriaBuilder, Serializab
public <E, C extends Collection<E>> Predicate isNotMember(Expression<E> eExpression, Expression<C> cExpression) {
return isMember(eExpression, cExpression).not();
}
private <X, T, V extends T, K extends JoinImplementor> K treat(
Join<X, T> join,
Class<V> type,
BiFunction<Join<X, T>, Class<V>, K> f) {
final Set<Join<X, ?>> joins = join.getParent().getJoins();
final K treatAs = f.apply( join, type );
joins.add(treatAs);
return treatAs;
}
}

View File

@ -15,11 +15,15 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext;
* @author Steve Ebersole
*/
public interface FromImplementor<Z,X> extends PathImplementor<X>, From<Z,X> {
public void prepareAlias(RenderingContext renderingContext);
public String renderTableExpression(RenderingContext renderingContext);
void prepareAlias(RenderingContext renderingContext);
String renderTableExpression(RenderingContext renderingContext);
public FromImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
public void prepareCorrelationDelegate(FromImplementor<Z,X> parent);
public FromImplementor<Z, X> getCorrelationParent();
FromImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
void prepareCorrelationDelegate(FromImplementor<Z,X> parent);
FromImplementor<Z, X> getCorrelationParent();
default boolean shouldBeRendered(){
return true;
}
}

View File

@ -336,11 +336,13 @@ public class QueryStructure<T> 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() );
}
}
}

View File

@ -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<O,E>
@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<O,E>
return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")";
}
@Override
protected ManagedType<T> locateManagedType() {
return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType );
}
@Override
public String getPathIdentifier() {
return "treat(" + getAlias() + " as " + treatAsType.getName() + ")";

View File

@ -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<O,E>
@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<O,E>
return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")";
}
@Override
protected ManagedType<T> locateManagedType() {
return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType );
}
@Override
public String getPathIdentifier() {
return "treat(" + getAlias() + " as " + treatAsType.getName() + ")";

View File

@ -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<O,K,V>
@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<O,K,V>
return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")";
}
@Override
protected ManagedType<T> locateManagedType() {
return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType );
}
@Override
public String getPathIdentifier() {
return "treat(" + getAlias() + " as " + treatAsType.getName() + ")";

View File

@ -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<O,E>
@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<O,E>
return "treat(" + original.render( renderingContext ) + " as " + treatAsType.getName() + ")";
}
@Override
protected ManagedType<T> locateManagedType() {
return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType );
}
@Override
public String getPathIdentifier() {
return "treat(" + getAlias() + " as " + treatAsType.getName() + ")";

View File

@ -133,12 +133,40 @@ public class SingularAttributeJoin<O,X> extends AbstractJoinImpl<O,X> {
@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<T> locateManagedType() {
return criteriaBuilder().getEntityManagerFactory().getMetamodel().managedType( treatAsType );
}
@Override
public boolean shouldBeRendered() {
if ( getJoins().size() > 0 ) {
return true;
}
else {
return false;
}
}
@Override