mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 00:24:57 +00:00
HHH-16776 more consistent reporting of errors in attribute paths
and squash some warnings
This commit is contained in:
parent
9075cf84fb
commit
5110fd4653
@ -39,7 +39,7 @@
|
||||
import org.hibernate.metamodel.model.domain.internal.AttributeContainer;
|
||||
import org.hibernate.metamodel.model.domain.internal.DomainModelHelper;
|
||||
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
@ -121,9 +121,8 @@ public void visitDeclaredAttributes(Consumer<? super PersistentAttribute<J, ?>>
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<Attribute<? super J, ?>> getAttributes() {
|
||||
final HashSet attributes = new LinkedHashSet( getDeclaredAttributes() );
|
||||
final HashSet<Attribute<? super J, ?>> attributes = new LinkedHashSet<>( getDeclaredAttributes() );
|
||||
|
||||
if ( getSuperType() != null ) {
|
||||
attributes.addAll( getSuperType().getAttributes() );
|
||||
@ -133,39 +132,36 @@ public void visitDeclaredAttributes(Consumer<? super PersistentAttribute<J, ?>>
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<Attribute<J, ?>> getDeclaredAttributes() {
|
||||
final boolean isDeclaredSingularAttributesEmpty = CollectionHelper.isEmpty( declaredSingularAttributes );
|
||||
final boolean isDeclaredPluralAttributes = CollectionHelper.isEmpty( declaredPluralAttributes );
|
||||
if ( isDeclaredSingularAttributesEmpty && isDeclaredPluralAttributes ) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
final HashSet attributes;
|
||||
final HashSet<Attribute<J, ?>> attributes;
|
||||
if ( !isDeclaredSingularAttributesEmpty ) {
|
||||
attributes = new LinkedHashSet( declaredSingularAttributes.values() );
|
||||
attributes = new LinkedHashSet<>( declaredSingularAttributes.values() );
|
||||
if ( !isDeclaredPluralAttributes ) {
|
||||
attributes.addAll( declaredPluralAttributes.values() );
|
||||
}
|
||||
}
|
||||
else {
|
||||
attributes = new LinkedHashSet( declaredPluralAttributes.values() );
|
||||
attributes = new LinkedHashSet<>( declaredPluralAttributes.values() );
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public PersistentAttribute<? super J,?> getAttribute(String name) {
|
||||
final PersistentAttribute attribute = findAttribute( name );
|
||||
final PersistentAttribute<? super J,?> attribute = findAttribute( name );
|
||||
checkNotNull( "Attribute", attribute, name );
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public PersistentAttribute<? super J,?> findAttribute(String name) {
|
||||
// first look at declared attributes
|
||||
PersistentAttribute attribute = findDeclaredAttribute( name );
|
||||
PersistentAttribute<? super J,?> attribute = findDeclaredAttribute( name );
|
||||
if ( attribute != null ) {
|
||||
return attribute;
|
||||
}
|
||||
@ -177,20 +173,18 @@ public PersistentAttribute<? super J,?> findAttribute(String name) {
|
||||
}
|
||||
}
|
||||
|
||||
for ( ManagedDomainType subType : subTypes ) {
|
||||
for ( ManagedDomainType<?> subType : subTypes ) {
|
||||
PersistentAttribute subTypeAttribute = subType.findSubTypesAttribute( name );
|
||||
if ( subTypeAttribute != null ) {
|
||||
if ( attribute != null && !isCompatible( attribute, subTypeAttribute ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
new SemanticException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes: ['%s', '%s']",
|
||||
name,
|
||||
getTypeName(),
|
||||
attribute.getDeclaringType().getTypeName(),
|
||||
subTypeAttribute.getDeclaringType().getTypeName()
|
||||
)
|
||||
throw new PathException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes: '%s', '%s'",
|
||||
name,
|
||||
getTypeName(),
|
||||
attribute.getDeclaringType().getTypeName(),
|
||||
subTypeAttribute.getDeclaringType().getTypeName()
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -236,12 +230,12 @@ private boolean isCompatible(PersistentAttribute<?, ?> attribute1, PersistentAtt
|
||||
@Override
|
||||
public PersistentAttribute<? super J, ?> findSubTypesAttribute(String name) {
|
||||
// first look at declared attributes
|
||||
PersistentAttribute attribute = findDeclaredAttribute( name );
|
||||
PersistentAttribute<? super J,?> attribute = findDeclaredAttribute( name );
|
||||
if ( attribute != null ) {
|
||||
return attribute;
|
||||
}
|
||||
|
||||
for ( ManagedDomainType subType : subTypes ) {
|
||||
for ( ManagedDomainType<? extends J> subType : subTypes ) {
|
||||
PersistentAttribute subTypeAttribute = subType.findAttribute( name );
|
||||
if ( subTypeAttribute != null ) {
|
||||
return subTypeAttribute;
|
||||
@ -252,10 +246,9 @@ private boolean isCompatible(PersistentAttribute<?, ?> attribute1, PersistentAtt
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public PersistentAttribute<J,?> findDeclaredAttribute(String name) {
|
||||
// try singular attribute
|
||||
PersistentAttribute attribute = declaredSingularAttributes.get( name );
|
||||
PersistentAttribute<J,?> attribute = declaredSingularAttributes.get( name );
|
||||
if ( attribute != null ) {
|
||||
return attribute;
|
||||
}
|
||||
@ -274,9 +267,8 @@ public PersistentAttribute<J,?> findDeclaredAttribute(String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public PersistentAttribute<J,?> getDeclaredAttribute(String name) {
|
||||
PersistentAttribute attr = findDeclaredAttribute( name );
|
||||
PersistentAttribute<J,?> attr = findDeclaredAttribute( name );
|
||||
checkNotNull( "Attribute", attr, name );
|
||||
return attr;
|
||||
}
|
||||
@ -304,9 +296,8 @@ public String getTypeName() {
|
||||
// Singular attributes
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<SingularAttribute<? super J, ?>> getSingularAttributes() {
|
||||
HashSet attributes = new HashSet<>( declaredSingularAttributes.values() );
|
||||
HashSet<SingularAttribute<? super J, ?>> attributes = new HashSet<>( declaredSingularAttributes.values() );
|
||||
if ( getSuperType() != null ) {
|
||||
attributes.addAll( getSuperType().getSingularAttributes() );
|
||||
}
|
||||
@ -319,17 +310,15 @@ public String getTypeName() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public SingularPersistentAttribute<? super J, ?> getSingularAttribute(String name) {
|
||||
SingularPersistentAttribute attribute = findSingularAttribute( name );
|
||||
SingularPersistentAttribute<? super J, ?> attribute = findSingularAttribute( name );
|
||||
checkNotNull( "SingularAttribute", attribute, name );
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public SingularPersistentAttribute<? super J, ?> findSingularAttribute(String name) {
|
||||
SingularPersistentAttribute attribute = findDeclaredSingularAttribute( name );
|
||||
SingularPersistentAttribute<? super J, ?> attribute = findDeclaredSingularAttribute( name );
|
||||
if ( attribute == null && getSuperType() != null ) {
|
||||
attribute = getSuperType().findSingularAttribute( name );
|
||||
}
|
||||
@ -339,7 +328,7 @@ public String getTypeName() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <Y> SingularPersistentAttribute<? super J, Y> getSingularAttribute(String name, Class<Y> type) {
|
||||
SingularAttribute attribute = findSingularAttribute( name );
|
||||
SingularAttribute<? super J, ?> attribute = findSingularAttribute( name );
|
||||
checkTypeForSingleAttribute( attribute, name, type );
|
||||
return (SingularPersistentAttribute) attribute;
|
||||
}
|
||||
@ -362,7 +351,7 @@ public <Y> SingularPersistentAttribute<? super J, Y> getSingularAttribute(String
|
||||
public <Y> SingularPersistentAttribute<J, Y> getDeclaredSingularAttribute(String name, Class<Y> javaType) {
|
||||
final SingularAttribute attr = findDeclaredSingularAttribute( name );
|
||||
checkTypeForSingleAttribute( attr, name, javaType );
|
||||
return (SingularPersistentAttribute) attr;
|
||||
return (SingularPersistentAttribute<J, Y>) attr;
|
||||
}
|
||||
|
||||
private <Y> void checkTypeForSingleAttribute(
|
||||
@ -747,7 +736,6 @@ public InFlightAccess<J> getInFlightAccess() {
|
||||
|
||||
protected class InFlightAccessImpl implements InFlightAccess<J> {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addAttribute(PersistentAttribute<J,?> attribute) {
|
||||
if ( attribute instanceof SingularPersistentAttribute ) {
|
||||
declaredSingularAttributes.put( attribute.getName(), (SingularPersistentAttribute<J, ?>) attribute );
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.TerminalPathException;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
@ -43,7 +44,8 @@ public BasicDomainType<J> getSqmPathType() {
|
||||
|
||||
@Override
|
||||
public SqmPathSource<?> findSubPathSource(String name) {
|
||||
throw new IllegalStateException( "Basic paths cannot be dereferenced" );
|
||||
throw new TerminalPathException( "Path '" + pathModel.getPathName()
|
||||
+ "' has no attribute '" + name + "'" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,7 +152,7 @@ public SqmAttributeJoin<D,J> createSqmJoin(
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return new SqmSingularJoin(
|
||||
return new SqmSingularJoin<D,J>(
|
||||
lhs,
|
||||
this,
|
||||
alias,
|
||||
@ -166,7 +166,7 @@ public SqmAttributeJoin<D,J> createSqmJoin(
|
||||
public NavigablePath createNavigablePath(SqmPath parent, String alias) {
|
||||
if ( parent == null ) {
|
||||
throw new IllegalArgumentException(
|
||||
"`lhs` cannot be null for a sub-navigable reference - " + getName()
|
||||
"LHS cannot be null for a sub-navigable reference - " + getName()
|
||||
);
|
||||
}
|
||||
final SqmPathSource<?> parentPathSource = parent.getReferencedPathSource();
|
||||
@ -216,7 +216,7 @@ public Identifier(
|
||||
public NavigablePath createNavigablePath(SqmPath parent, String alias) {
|
||||
if ( parent == null ) {
|
||||
throw new IllegalArgumentException(
|
||||
"`lhs` cannot be null for a sub-navigable reference - " + getName()
|
||||
"LHS cannot be null for a sub-navigable reference - " + getName()
|
||||
);
|
||||
}
|
||||
NavigablePath navigablePath = parent.getNavigablePath();
|
||||
@ -280,7 +280,7 @@ public boolean isOptional() {
|
||||
@Override
|
||||
public boolean isAssociation() {
|
||||
return getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE
|
||||
|| getPersistentAttributeType() == PersistentAttributeType.ONE_TO_ONE;
|
||||
|| getPersistentAttributeType() == PersistentAttributeType.ONE_TO_ONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -209,7 +209,7 @@
|
||||
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.property.access.spi.Setter;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.named.NamedQueryMemento;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.sql.internal.SQLQueryParser;
|
||||
@ -235,7 +235,6 @@
|
||||
import org.hibernate.sql.ast.tree.expression.AliasedExpression;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||
import org.hibernate.sql.ast.tree.from.StandardTableGroup;
|
||||
@ -5718,22 +5717,20 @@ public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
|
||||
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
|
||||
if ( subDefinedAttribute != null ) {
|
||||
if ( attribute != null && !MappingModelHelper.isCompatibleModelPart( attribute, subDefinedAttribute ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
new SemanticException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes: ['%s', '%s']",
|
||||
name,
|
||||
getJavaType().getJavaType().getTypeName(),
|
||||
attribute.asAttributeMapping().getDeclaringType()
|
||||
.getJavaType()
|
||||
.getJavaType()
|
||||
.getTypeName(),
|
||||
subDefinedAttribute.asAttributeMapping().getDeclaringType()
|
||||
.getJavaType()
|
||||
.getJavaType()
|
||||
.getTypeName()
|
||||
)
|
||||
throw new PathException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes: '%s', '%s'",
|
||||
name,
|
||||
getJavaType().getJavaType().getTypeName(),
|
||||
attribute.asAttributeMapping().getDeclaringType()
|
||||
.getJavaType()
|
||||
.getJavaType()
|
||||
.getTypeName(),
|
||||
subDefinedAttribute.asAttributeMapping().getDeclaringType()
|
||||
.getJavaType()
|
||||
.getJavaType()
|
||||
.getTypeName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.query;
|
||||
|
||||
/**
|
||||
* Indicates that an element of a path did not resolve to
|
||||
* a mapped program element.
|
||||
*
|
||||
* @apiNote extends {@link IllegalArgumentException} to
|
||||
* satisfy a questionable requirement of the JPA criteria
|
||||
* query API
|
||||
*
|
||||
* @since 6.3
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class PathElementException extends IllegalArgumentException {
|
||||
public PathElementException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -12,6 +12,9 @@
|
||||
* Indicates an attempt to use a path in an unsupported way
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
* @see PathElementException
|
||||
* @see TerminalPathException
|
||||
*/
|
||||
public class PathException extends HibernateException {
|
||||
public PathException(String message) {
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.query;
|
||||
|
||||
/**
|
||||
* Indicates an attempt to dereference a terminal path
|
||||
* (usually a path referring to something of basic type)
|
||||
*
|
||||
* @apiNote extends {@link IllegalStateException} to
|
||||
* satisfy a questionable requirement of the JPA criteria
|
||||
* query API
|
||||
*
|
||||
* @since 6.3
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class TerminalPathException extends IllegalStateException {
|
||||
public TerminalPathException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
import jakarta.persistence.metamodel.Bindable;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.PathElementException;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.sqm.tree.SqmExpressibleAccessor;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
@ -41,7 +41,7 @@ public interface SqmPathSource<J> extends SqmExpressible<J>, Bindable<J>, SqmExp
|
||||
/**
|
||||
* Find a SqmPathSource by name relative to this source.
|
||||
*
|
||||
* returns null if the subPathSource is not found
|
||||
* @return null if the subPathSource is not found
|
||||
*
|
||||
* @throws IllegalStateException to indicate that this source cannot be de-referenced
|
||||
*/
|
||||
@ -56,14 +56,12 @@ public interface SqmPathSource<J> extends SqmExpressible<J>, Bindable<J>, SqmExp
|
||||
default SqmPathSource<?> getSubPathSource(String name) {
|
||||
final SqmPathSource<?> subPathSource = findSubPathSource( name );
|
||||
if ( subPathSource == null ) {
|
||||
throw new IllegalArgumentException(
|
||||
new SemanticException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve attribute '%s' of '%s'",
|
||||
name,
|
||||
getExpressible().getTypeName()
|
||||
)
|
||||
throw new PathElementException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not resolve attribute '%s' of '%s'",
|
||||
name,
|
||||
getExpressible().getTypeName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
@ -52,16 +51,6 @@ public NonAggregatedCompositeSimplePath<T> copy(SqmCopyContext context) {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<?> resolvePathPart(
|
||||
String name,
|
||||
boolean isTerminal,
|
||||
SqmCreationState creationState) {
|
||||
final SqmPath<?> sqmPath = get( name );
|
||||
creationState.getProcessingStateStack().getCurrent().getPathRegistry().register( sqmPath );
|
||||
return sqmPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitNonAggregatedCompositeValuedPath( this );
|
||||
@ -70,7 +59,7 @@ public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
|
||||
@Override
|
||||
public <S extends T> SqmTreatedPath<T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
|
||||
throw new PathException( "Non Aggregate composite paths cannot be TREAT-ed" );
|
||||
throw new PathException( "Non-aggregate composite paths cannot be TREAT-ed" );
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user