HHH-17283 Correct tuple length for subqueries and attribute joins

This commit is contained in:
Marco Belladelli 2023-10-06 10:39:06 +02:00
parent c00ca3e5ec
commit 4d693f484d
7 changed files with 34 additions and 32 deletions

View File

@ -30,4 +30,8 @@ public interface DomainType<J> extends SqmExpressible<J> {
default DomainType<J> getSqmType() { default DomainType<J> getSqmType() {
return this; return this;
} }
default int getTupleLength() {
return 1;
}
} }

View File

@ -8,13 +8,15 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable; import java.io.Serializable;
import org.hibernate.graph.internal.SubGraphImpl;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.AbstractManagedType; import org.hibernate.metamodel.model.domain.AbstractManagedType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType; import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor; import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type;
/** /**
* Implementation of {@link jakarta.persistence.metamodel.EmbeddableType}. * Implementation of {@link jakarta.persistence.metamodel.EmbeddableType}.
* *
@ -39,4 +41,12 @@ public class EmbeddableTypeImpl<J>
public PersistenceType getPersistenceType() { public PersistenceType getPersistenceType() {
return PersistenceType.EMBEDDABLE; return PersistenceType.EMBEDDABLE;
} }
public int getTupleLength() {
int count = 0;
for ( SingularAttribute<? super J, ?> attribute : getSingularAttributes() ) {
count += ( (DomainType<?>) attribute.getType() ).getTupleLength();
}
return count;
}
} }

View File

@ -7,7 +7,6 @@
package org.hibernate.query.sqm.tree.domain; package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.PersistentAttribute; import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.criteria.JpaExpression; import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate; import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
@ -15,15 +14,12 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmJoinable; import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.spi.SqmCreationHelper; import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom; import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate; import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.jboss.logging.Logger;
import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Predicate;
@ -140,5 +136,4 @@ public abstract class AbstractSqmAttributeJoin<O,T>
public JoinType getJoinType() { public JoinType getJoinType() {
return getSqmJoinType().getCorrespondingJpaJoinType(); return getSqmJoinType().getCorrespondingJpaJoinType();
} }
} }

View File

@ -6,8 +6,6 @@
*/ */
package org.hibernate.query.sqm.tree.domain; package org.hibernate.query.sqm.tree.domain;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.SingularAttribute;
import org.hibernate.metamodel.model.domain.DomainType; import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType; import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType;
@ -22,8 +20,6 @@ import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import java.util.Set;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@ -79,21 +75,6 @@ public class SqmEmbeddedValuedSimplePath<T>
return this; return this;
} }
@Override
public Integer getTupleLength() {
final EmbeddableDomainType<?> sqmPathType = (EmbeddableDomainType<?>) getReferencedPathSource().getSqmPathType();
final Set<? extends SingularAttribute<?, ?>> attributes = sqmPathType.getSingularAttributes();
return length(attributes);
}
private int length(Set<? extends SingularAttribute<?, ?>> attributes) {
int length = 0;
for (Attribute<?, ?> attribute : attributes) {
length += get(attribute.getName()).getTupleLength();
}
return length;
}
@Override @Override
public DomainType<T> getSqmType() { public DomainType<T> getSqmType() {
return getReferencedPathSource().getSqmType(); return getReferencedPathSource().getSqmType();

View File

@ -58,10 +58,6 @@ public interface SqmExpression<T> extends SqmSelectableNode<T>, JpaExpression<T>
jpaSelectionConsumer.accept( this ); jpaSelectionConsumer.accept( this );
} }
default Integer getTupleLength() {
return 1;
}
@Override @Override
SqmExpression<Long> asLong(); SqmExpression<Long> asLong();

View File

@ -9,6 +9,7 @@ package org.hibernate.query.sqm.tree.select;
import java.util.function.Consumer; import java.util.function.Consumer;
import jakarta.persistence.criteria.Selection; import jakarta.persistence.criteria.Selection;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.query.criteria.JpaSelection; import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.SqmTypedNode;
@ -32,4 +33,9 @@ public interface SqmSelectableNode<T> extends JpaSelection<T>, SqmTypedNode<T> {
@Override @Override
SqmSelectableNode<T> copy(SqmCopyContext context); SqmSelectableNode<T> copy(SqmCopyContext context);
default Integer getTupleLength() {
final DomainType<T> sqmType = getNodeType() == null ? null : getNodeType().getSqmType();
return sqmType == null ? 1 : sqmType.getTupleLength();
}
} }

View File

@ -154,7 +154,17 @@ public class SqmSubQuery<T> extends AbstractSqmSelectQuery<T> implements SqmSele
@Override @Override
public Integer getTupleLength() { public Integer getTupleLength() {
final SqmSelectClause selectClause = getQuerySpec().getSelectClause(); final SqmSelectClause selectClause = getQuerySpec().getSelectClause();
return selectClause == null ? null : selectClause.getSelectionItems().size(); return selectClause != null ?
getTupleLength( selectClause.getSelectionItems() ) :
null;
}
private int getTupleLength(List<SqmSelectableNode<?>> selectionItems) {
int count = 0;
for ( SqmSelectableNode<?> selection : selectionItems ) {
count += selection.getTupleLength();
}
return count;
} }
@Override @Override