cosmetic improvements to HQL error reporting

makes the messages and exception types a bit more consistent
This commit is contained in:
Gavin King 2022-01-08 02:13:34 +01:00
parent 3103d84949
commit 6c83e1d0ec
8 changed files with 29 additions and 13 deletions

View File

@ -10,12 +10,12 @@ import java.lang.reflect.Field;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.SemanticException;
import org.hibernate.query.hql.HqlLogging; import org.hibernate.query.hql.HqlLogging;
import org.hibernate.query.hql.spi.DotIdentifierConsumer; import org.hibernate.query.hql.spi.DotIdentifierConsumer;
import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState; import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.hql.spi.SqmPathRegistry; import org.hibernate.query.hql.spi.SqmPathRegistry;
import org.hibernate.query.sqm.ParsingException;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.spi.SqmCreationContext; import org.hibernate.query.sqm.spi.SqmCreationContext;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -252,7 +252,12 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
} }
} }
throw new ParsingException( "Could not interpret dot-ident : " + path ); throw new SemanticException(
String.format(
"Could not interpret path expression '%s'",
path
)
);
} }
protected void validateAsRoot(SqmFrom<?, ?> pathRoot) { protected void validateAsRoot(SqmFrom<?, ?> pathRoot) {

View File

@ -1071,7 +1071,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
.getPathRegistry() .getPathRegistry()
.findAliasedNodeByPosition( position ); .findAliasedNodeByPosition( position );
if ( nodeByPosition == null ) { if ( nodeByPosition == null ) {
throw new ParsingException( "Numeric literal `" + position + "` used in group-by does not match a registered select-item" ); throw new ParsingException( "Numeric literal '" + position + "' used in group-by does not match a registered select-item" );
} }
return new SqmAliasedNodeRef( position, integerDomainType, creationContext.getNodeBuilder() ); return new SqmAliasedNodeRef( position, integerDomainType, creationContext.getNodeBuilder() );
@ -1474,9 +1474,9 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
); );
return correlation.getCorrelatedRoot(); return correlation.getCorrelatedRoot();
} }
throw new SemanticException( "Could not resolve entity reference or correlation path: " + name ); throw new SemanticException( "Could not resolve entity or correlation path '" + name + "'" );
} }
throw new SemanticException( "Could not resolve entity reference: " + name ); throw new SemanticException( "Could not resolve entity '" + name + "'" );
} }
checkFQNEntityNameJpaComplianceViolationIfNeeded( name, entityDescriptor ); checkFQNEntityNameJpaComplianceViolationIfNeeded( name, entityDescriptor );

View File

@ -19,6 +19,7 @@ import jakarta.persistence.metamodel.SingularAttribute;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.model.domain.PersistentAttribute; import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression; import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
@ -142,7 +143,12 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
final SqmPathSource<?> subNavigable = getReferencedPathSource().findSubPathSource( attributeName ); final SqmPathSource<?> subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
if ( subNavigable == null ) { if ( subNavigable == null ) {
throw new IllegalArgumentException( "Could not resolve attribute named `" + attributeName + "` relative to `" + getNavigablePath() + "`" ); throw new SemanticException(
String.format(
"Could not resolve attribute '%s' of '%s'",
attributeName, getNavigablePath()
)
);
} }
return resolvePath( attributeName, subNavigable ); return resolvePath( attributeName, subNavigable );
} }

View File

@ -11,7 +11,6 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath; import org.hibernate.query.NavigablePath;
import org.hibernate.query.PathException; import org.hibernate.query.PathException;
import org.hibernate.query.SemanticException; import org.hibernate.query.SemanticException;
import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState; import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SemanticQueryWalker;
@ -50,7 +49,12 @@ public class SqmBasicValuedSimplePath<T>
String name, String name,
boolean isTerminal, boolean isTerminal,
SqmCreationState creationState) { SqmCreationState creationState) {
throw new SemanticException( "Basic-valued path [" + getNavigablePath() + "] cannot be de-referenced : " + name ); throw new SemanticException(
String.format(
"Could not interpret attribute '%s' of basic-valued path '%s'",
name, getNavigablePath()
)
);
} }

View File

@ -43,8 +43,8 @@ public class LoaderWithInvalidQueryTest extends BaseEntityManagerFunctionalTestC
HibernateException rootCause = (HibernateException) ExceptionUtil.rootCause( expected ); HibernateException rootCause = (HibernateException) ExceptionUtil.rootCause( expected );
Throwable[] suppressed = rootCause.getSuppressed(); Throwable[] suppressed = rootCause.getSuppressed();
assertEquals( 2, suppressed.length ); assertEquals( 2, suppressed.length );
assertTrue( ExceptionUtil.rootCause( suppressed[0] ).getMessage().contains( "Could not resolve attribute named `valid`" ) ); assertTrue( ExceptionUtil.rootCause( suppressed[0] ).getMessage().contains( "Could not resolve attribute 'valid'" ) );
assertTrue( ExceptionUtil.rootCause( suppressed[1] ).getMessage().contains( "Could not resolve entity reference: _Person" ) ); assertTrue( ExceptionUtil.rootCause( suppressed[1] ).getMessage().contains( "Could not resolve entity '_Person'" ) );
} }
} }

View File

@ -72,7 +72,7 @@ public class JoinOnClauseTest extends BaseEntityManagerFunctionalTestCase {
fail( "Referring to a join alias in the on clause that is joined later should be invalid!" ); fail( "Referring to a join alias in the on clause that is joined later should be invalid!" );
} }
catch (IllegalArgumentException ex) { catch (IllegalArgumentException ex) {
assertTrue( ex.getCause().getCause().getMessage().endsWith( ": author2" ) ); assertTrue( ex.getCause().getMessage().contains( "'author2'" ) );
} }
} ); } );
} }

View File

@ -76,7 +76,7 @@ public class MappedSuperclassInheritanceTest extends BaseEntityManagerFunctional
fail(); fail();
} catch (Exception expected) { } catch (Exception expected) {
SemanticException rootException = (SemanticException) ExceptionUtil.rootCause( expected); SemanticException rootException = (SemanticException) ExceptionUtil.rootCause( expected);
assertEquals("Could not resolve entity reference: Employee", rootException.getMessage()); assertEquals("Could not resolve entity 'Employee'", rootException.getMessage());
} }
} ); } );
} }

View File

@ -17,6 +17,7 @@ import org.hibernate.orm.test.jpa.metamodel.Order;
import org.hibernate.orm.test.jpa.metamodel.Thing; import org.hibernate.orm.test.jpa.metamodel.Thing;
import org.hibernate.orm.test.jpa.metamodel.ThingWithQuantity; import org.hibernate.orm.test.jpa.metamodel.ThingWithQuantity;
import org.hibernate.query.SemanticException;
import org.hibernate.testing.orm.junit.ExpectedException; import org.hibernate.testing.orm.junit.ExpectedException;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -66,7 +67,7 @@ public class AbstractPathImplTest extends AbstractMetamodelSpecificTest {
em.close(); em.close();
} }
@ExpectedException(value = IllegalArgumentException.class) @ExpectedException(value = SemanticException.class)
@Test @Test
public void testGetNonExistingAttributeViaName() { public void testGetNonExistingAttributeViaName() {
EntityManager em = getOrCreateEntityManager(); EntityManager em = getOrCreateEntityManager();