diff --git a/hibernate-core/src/main/java/org/hibernate/QueryException.java b/hibernate-core/src/main/java/org/hibernate/QueryException.java
index 5e4afc5b38..25d73b1f4a 100644
--- a/hibernate-core/src/main/java/org/hibernate/QueryException.java
+++ b/hibernate-core/src/main/java/org/hibernate/QueryException.java
@@ -7,8 +7,22 @@
package org.hibernate;
/**
- * A problem occurred translating a Hibernate query to SQL
- * due to invalid query syntax, or some similar problem.
+ * A problem occurred translating a Hibernate query to SQL due to illegal query
+ * syntax, an operation which is not well-typed, an unresolvable reference to
+ * an entity or attribute, an unknown named query, or any similar problem. This
+ * exception type is not used to represent failures that occur while executing
+ * a query or reading the result set of a query.
+ *
+ * The two most important subtypes are:
+ *
+ * - {@link org.hibernate.query.SyntaxException}, which represents a syntax
+ * error in the HQL query, and
+ *
- {@link org.hibernate.query.SemanticException}, which represents an error
+ * in the semantics of the query.
+ *
+ *
+ * @see org.hibernate.query.SemanticException
+ * @see org.hibernate.query.SyntaxException
*/
public class QueryException extends HibernateException {
private final String queryString;
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java
index e92ac0d376..8d2a4e389e 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java
@@ -8,7 +8,7 @@ package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.ReturnableType;
-import org.hibernate.query.TerminalPathException;
+import org.hibernate.query.sqm.TerminalPathException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java
index 806a79581d..fa330baa6f 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java
@@ -47,7 +47,7 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
-import org.hibernate.query.EntityReferenceException;
+import org.hibernate.query.sqm.EntityTypeException;
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.descriptor.java.EnumJavaType;
@@ -164,7 +164,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
public EntityDomainType resolveHqlEntityReference(String entityName) {
final EntityDomainType hqlEntityReference = getHqlEntityReference( entityName );
if ( hqlEntityReference == null ) {
- throw new EntityReferenceException( "Could not resolve entity reference: " + entityName );
+ throw new EntityTypeException( "Could not resolve entity name '" + entityName + "'", entityName );
}
return hqlEntityReference;
}
@@ -444,7 +444,8 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
// otherwise, try to handle it as a polymorphic reference
{
- final EntityDomainType polymorphicDomainType = (EntityDomainType) polymorphicEntityReferenceMap.get( javaType );
+ final EntityDomainType polymorphicDomainType =
+ (EntityDomainType) polymorphicEntityReferenceMap.get( javaType );
if ( polymorphicDomainType != null ) {
return polymorphicDomainType;
}
@@ -495,7 +496,7 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
}
}
- throw new EntityReferenceException( "Could not resolve entity reference : " + javaType.getName() );
+ throw new EntityTypeException( "Could not resolve entity class '" + javaType.getName() + "'", javaType.getName() );
}
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/query/EntityReferenceException.java b/hibernate-core/src/main/java/org/hibernate/query/EntityReferenceException.java
deleted file mode 100644
index dadacda4a9..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/query/EntityReferenceException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 a reference to an entity did not resolve to
- * a mapped entity class.
- *
- * @apiNote extends {@link IllegalArgumentException} to
- * satisfy a questionable requirement of the JPA criteria
- * query API
- *
- * @since 6.3
- *
- * @author Gavin King
- */
-public class EntityReferenceException extends IllegalArgumentException {
- public EntityReferenceException(String message) {
- super(message);
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/query/NamedQueryValidationException.java b/hibernate-core/src/main/java/org/hibernate/query/NamedQueryValidationException.java
index 0dc44f249f..71b5d1b6f6 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/NamedQueryValidationException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/NamedQueryValidationException.java
@@ -13,7 +13,10 @@ import java.util.Map;
/**
* Indicates that validation and translation of one or more named
- * queries failed at initialization time.
+ * queries failed at initialization time. This exception packages
+ * every {@link org.hibernate.QueryException} that occurred for an
+ * invalid HQL/JPQL query, together with any exceptions that indicate
+ * problems with named native SQL queries.
*
* @author Gavin King
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/query/PathException.java b/hibernate-core/src/main/java/org/hibernate/query/PathException.java
index ad05feb636..d13e0aa711 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/PathException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/PathException.java
@@ -7,23 +7,22 @@
package org.hibernate.query;
/**
- * Indicates an attempt to use a path in an unsupported way
+ * Indicates a problem with a path expression in HQL/JPQL.
*
* @author Steve Ebersole
*
- * @see PathElementException
- * @see TerminalPathException
+ * @see org.hibernate.query.sqm.UnknownPathException
*/
public class PathException extends SemanticException {
public PathException(String message) {
super( message );
}
- /**
- * @deprecated This is currently unused
- */
- @Deprecated(forRemoval = true, since = "6.3")
public PathException(String message, Exception cause) {
super( message, cause );
}
+
+ public PathException(String message, String hql, Exception cause) {
+ super(message, hql, cause);
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/query/QueryTypeMismatchException.java b/hibernate-core/src/main/java/org/hibernate/query/QueryTypeMismatchException.java
index 60be1f40c5..7109c3668a 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/QueryTypeMismatchException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/QueryTypeMismatchException.java
@@ -9,7 +9,7 @@ package org.hibernate.query;
import org.hibernate.HibernateException;
/**
- * Indicates a mismatch between a Query's expected and actual result types
+ * Indicates a mismatch between the expected and actual result types of a query.
*
* @author Steve Ebersole
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/query/UnknownNamedQueryException.java b/hibernate-core/src/main/java/org/hibernate/query/UnknownNamedQueryException.java
index 007d77d912..c38a22ae41 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/UnknownNamedQueryException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/UnknownNamedQueryException.java
@@ -9,10 +9,12 @@ package org.hibernate.query;
import org.hibernate.QueryException;
/**
- * Indicates a request for a named-query when no query is
- * registered under that name
+ * Occurs when a named query is requested, and there is no known
+ * HQL or native SQL query registered under the given name.
*
* @author Steve Ebersole
+ *
+ * @see org.hibernate.query.named.NamedObjectRepository
*/
public class UnknownNamedQueryException extends QueryException {
public UnknownNamedQueryException(String queryName) {
diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java
index fa5ebd3f7a..e4db357631 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java
@@ -57,7 +57,7 @@ import org.hibernate.query.ParameterLabelException;
import org.hibernate.query.PathException;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.SemanticException;
-import org.hibernate.query.TerminalPathException;
+import org.hibernate.query.sqm.TerminalPathException;
import org.hibernate.query.criteria.JpaCteCriteria;
import org.hibernate.query.criteria.JpaCteCriteriaAttribute;
import org.hibernate.query.criteria.JpaCteCriteriaType;
diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java
index bb422f9b7b..3c8b2b6d49 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java
@@ -14,15 +14,17 @@ import org.antlr.v4.runtime.NoViableAltException;
import org.hibernate.QueryException;
import org.hibernate.grammars.hql.HqlLexer;
import org.hibernate.grammars.hql.HqlParser;
-import org.hibernate.query.EntityReferenceException;
-import org.hibernate.query.PathElementException;
+import org.hibernate.query.sqm.EntityTypeException;
+import org.hibernate.query.sqm.PathElementException;
import org.hibernate.query.SyntaxException;
-import org.hibernate.query.TerminalPathException;
+import org.hibernate.query.sqm.TerminalPathException;
import org.hibernate.query.hql.HqlLogging;
import org.hibernate.query.hql.HqlTranslator;
import org.hibernate.query.hql.spi.SqmCreationOptions;
import org.hibernate.query.sqm.InterpretationException;
import org.hibernate.query.sqm.ParsingException;
+import org.hibernate.query.sqm.UnknownEntityException;
+import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.internal.SqmTreePrinter;
import org.hibernate.query.sqm.spi.SqmCreationContext;
import org.hibernate.query.sqm.tree.SqmStatement;
@@ -78,9 +80,15 @@ public class StandardHqlTranslator implements HqlTranslator {
return sqmStatement;
}
- catch (QueryException | PathElementException | TerminalPathException | EntityReferenceException e) {
+ catch (QueryException e) {
throw e;
}
+ catch (PathElementException | TerminalPathException e) {
+ throw new UnknownPathException( e.getMessage(), query, e );
+ }
+ catch (EntityTypeException e) {
+ throw new UnknownEntityException( e.getMessage(), e.getReference(), e );
+ }
catch (Exception e) {
// this is some sort of "unexpected" exception, i.e. something buglike
throw new InterpretationException( query, e );
diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java
index 5f9104e709..00ab542e4a 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java
@@ -11,6 +11,7 @@ import java.util.Map;
import java.util.function.Consumer;
import org.hibernate.HibernateException;
+import org.hibernate.QueryException;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.query.NamedHqlQueryDefinition;
import org.hibernate.boot.query.NamedNativeQueryDefinition;
@@ -18,16 +19,18 @@ import org.hibernate.boot.query.NamedProcedureCallDefinition;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.procedure.spi.NamedCallableQueryMemento;
-import org.hibernate.query.EntityReferenceException;
+import org.hibernate.query.sqm.EntityTypeException;
import org.hibernate.query.NamedQueryValidationException;
-import org.hibernate.query.PathElementException;
-import org.hibernate.query.TerminalPathException;
+import org.hibernate.query.sqm.PathElementException;
+import org.hibernate.query.sqm.TerminalPathException;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.named.NamedResultSetMappingMemento;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryInterpretationCache;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
+import org.hibernate.query.sqm.UnknownEntityException;
+import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.jboss.logging.Logger;
@@ -239,21 +242,24 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
// Check named HQL queries
log.debugf( "Checking %s named HQL queries", sqmMementoMap.size() );
for ( NamedSqmQueryMemento hqlMemento : sqmMementoMap.values() ) {
+ final String queryString = hqlMemento.getHqlString();
+ final String registrationName = hqlMemento.getRegistrationName();
try {
- log.debugf( "Checking named HQL query: %s", hqlMemento.getRegistrationName() );
- String queryString = hqlMemento.getHqlString();
+ log.debugf( "Checking named HQL query: %s", registrationName );
interpretationCache.resolveHqlInterpretation(
queryString,
null,
s -> queryEngine.getHqlTranslator().translate( queryString, null )
);
}
- catch ( HibernateException e ) {
- errors.put( hqlMemento.getRegistrationName(), e );
+ catch ( QueryException e ) {
+ errors.put( registrationName, e );
}
- catch ( PathElementException | TerminalPathException | EntityReferenceException e ) {
- // JPA does not let these be HibernateExceptions in general
- errors.put( hqlMemento.getRegistrationName(), new HibernateException(e) );
+ catch ( PathElementException | TerminalPathException e ) {
+ errors.put( registrationName, new UnknownPathException( e.getMessage(), queryString, e ) );
+ }
+ catch ( EntityTypeException e ) {
+ errors.put( registrationName, new UnknownEntityException( e.getMessage(), e.getReference(), e ) );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/EntityTypeException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/EntityTypeException.java
new file mode 100644
index 0000000000..02e6e16829
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/EntityTypeException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.sqm;
+
+/**
+ * Indicates that a reference to an entity, that is, a given entity name
+ * or Java class object, did not resolve to a known mapped entity type.
+ *
+ * @apiNote extends {@link IllegalArgumentException} to
+ * satisfy a questionable requirement of the JPA
+ * criteria query API
+ *
+ * @since 6.3
+ *
+ * @author Gavin King
+ */
+public class EntityTypeException extends IllegalArgumentException {
+ private final String reference;
+
+ public EntityTypeException(String message, String reference) {
+ super(message);
+ this.reference = reference;
+ }
+
+ /**
+ * The entity name or the name of the Java class.
+ */
+ public String getReference() {
+ return reference;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/query/PathElementException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/PathElementException.java
similarity index 82%
rename from hibernate-core/src/main/java/org/hibernate/query/PathElementException.java
rename to hibernate-core/src/main/java/org/hibernate/query/sqm/PathElementException.java
index 77d75581f6..10371c064c 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/PathElementException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/PathElementException.java
@@ -4,15 +4,15 @@
* 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;
+package org.hibernate.query.sqm;
/**
* 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
+ * satisfy a questionable requirement of the JPA
+ * criteria query API
*
* @since 6.3
*
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java
index 9de2997524..92019d68ff 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java
@@ -11,7 +11,6 @@ import java.util.Locale;
import jakarta.persistence.metamodel.Bindable;
import org.hibernate.metamodel.model.domain.DomainType;
-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;
diff --git a/hibernate-core/src/main/java/org/hibernate/query/TerminalPathException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/TerminalPathException.java
similarity index 82%
rename from hibernate-core/src/main/java/org/hibernate/query/TerminalPathException.java
rename to hibernate-core/src/main/java/org/hibernate/query/sqm/TerminalPathException.java
index 398beaca77..31ddfe8d23 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/TerminalPathException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/TerminalPathException.java
@@ -4,15 +4,15 @@
* 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;
+package org.hibernate.query.sqm;
/**
* 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
+ * satisfy a questionable requirement of the JPA
+ * criteria query API
*
* @since 6.3
*
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java
index 4934df2cf4..ef159ee9ee 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java
@@ -9,14 +9,18 @@ package org.hibernate.query.sqm;
import org.hibernate.query.SemanticException;
/**
- * Indicates we were not able to resolve a given "path structure" as an entity name.
+ * Indicates a failure to resolve an entity name in HQL to a known mapped
+ * entity type.
*
- * @apiNote JPA generally requires this to be reported as the much less useful
- * {@link IllegalArgumentException}.
- *
- * todo (6.0) : account for this in the "exception conversion" handling
+ * @apiNote The JPA criteria API requires that this problem be reported
+ * as an {@link IllegalArgumentException}, and so we usually
+ * throw {@link EntityTypeException} from the SQM objects, and
+ * then wrap as an instance of this exception type in the
+ * {@link org.hibernate.query.hql.HqlTranslator}.
*
* @author Steve Ebersole
+ *
+ * @see EntityTypeException
*/
public class UnknownEntityException extends SemanticException {
private final String entityName;
@@ -30,6 +34,11 @@ public class UnknownEntityException extends SemanticException {
this.entityName = entityName;
}
+ public UnknownEntityException(String message, String entityName, Exception cause) {
+ super( message, cause );
+ this.entityName = entityName;
+ }
+
public String getEntityName() {
return entityName;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java
index d925631f9e..9d14f4229d 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java
@@ -8,30 +8,44 @@ package org.hibernate.query.sqm;
import java.util.Locale;
-import org.hibernate.query.SemanticException;
+import org.hibernate.query.PathException;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**
+ * Indicates a failure to resolve an element of a path expression in HQL/JPQL.
*
- *
- * todo (6.0) : account for this in the "exception conversion" handling
+ * @apiNote The JPA criteria API requires that this sort of problem be reported
+ * as an {@link IllegalArgumentException} or {@link IllegalStateException},
+ * and so we usually throw {@link PathElementException} or
+ * {@link TerminalPathException} from the SQM objects, and then wrap
+ * as an instance of this exception type in the
+ * {@link org.hibernate.query.hql.HqlTranslator}.
*
* @author Steve Ebersole
+ *
+ * @see PathElementException
+ * @see TerminalPathException
*/
-public class UnknownPathException extends SemanticException {
+public class UnknownPathException extends PathException {
+
+ public UnknownPathException(String message) {
+ super( message );
+ }
+
+ public UnknownPathException(String message, String hql, Exception cause) {
+ super( message, hql, cause );
+ }
+
+
public static UnknownPathException unknownSubPath(SqmPath base, String name) {
return new UnknownPathException(
String.format(
Locale.ROOT,
- "Could not resolve path `%s` relative to %s (%s)",
+ "Could not resolve path element '%s' relative to '%s' (%s)",
name,
base.getReferencedPathSource().getSqmPathType().getTypeName(),
base.getNavigablePath()
)
);
}
-
- private UnknownPathException(String message) {
- super( message );
- }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java
index 170f1416ac..21f9018346 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java
@@ -19,6 +19,7 @@ import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.PathException;
+import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.query.sqm.tree.from.SqmFrom;
@@ -121,7 +122,7 @@ public class BasicValuedPathInterpretation extends AbstractSqmPathInterpretat
}
}
- throw new PathException( "Path '" + sqmPath.getNavigablePath() + "' did not reference a known model part" );
+ throw new UnknownPathException( "Path '" + sqmPath.getNavigablePath() + "' did not reference a known model part" );
}
final TableReference tableReference = tableGroup.resolveTableReference(
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java
index 3a782001ef..33df742478 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBasicValuedSimplePath.java
@@ -7,6 +7,7 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
+import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationState;
@@ -70,7 +71,7 @@ public class SqmBasicValuedSimplePath
String name,
boolean isTerminal,
SqmCreationState creationState) {
- throw new PathException(
+ throw new UnknownPathException(
String.format(
"Could not interpret attribute '%s' of basic-valued path '%s'",
name, getNavigablePath()
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java
index 2e4a87a531..468b499465 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java
@@ -16,7 +16,7 @@ import jakarta.persistence.metamodel.PluralAttribute;
import jakarta.persistence.metamodel.SingularAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType;
-import org.hibernate.query.PathException;
+import org.hibernate.query.SemanticException;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.criteria.JpaPath;
import org.hibernate.query.hql.spi.SemanticPathPart;
@@ -138,7 +138,7 @@ public interface SqmPath extends SqmExpression, SemanticPathPart, JpaPath<
SqmExpression> selector,
boolean isTerminal,
SqmCreationState creationState) {
- throw new PathException( "Index operator applied to non-plural path '" + getNavigablePath() + "'" );
+ throw new SemanticException( "Index operator applied to non-plural path '" + getNavigablePath() + "'" );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant overrides
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralValuedSimplePath.java
index 3d0561b1f4..660d3548b3 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralValuedSimplePath.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralValuedSimplePath.java
@@ -90,7 +90,7 @@ public class SqmPluralValuedSimplePath extends AbstractSqmSimplePath {
String name,
boolean isTerminal,
SqmCreationState creationState) {
- // this is a reference to a collection outside the from-clause...
+ // this is a reference to a collection outside the from clause
final CollectionPart.Nature nature = CollectionPart.Nature.fromNameExact( name );
if ( nature == null ) {
throw new PathException( "Plural path '" + getNavigablePath()
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java
index cc5b4bd26f..74b6c068d7 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java
@@ -10,12 +10,12 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Locale;
-import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmExpressible;
+import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.type.descriptor.java.EnumJavaType;
@@ -85,7 +85,7 @@ public class SqmEnumLiteral> extends AbstractSqmExpression
String name,
boolean isTerminal,
SqmCreationState creationState) {
- throw new PathException(
+ throw new UnknownPathException(
String.format(
Locale.ROOT,
"Static enum reference [%s#%s] cannot be de-referenced",
@@ -100,7 +100,7 @@ public class SqmEnumLiteral> extends AbstractSqmExpression
SqmExpression> selector,
boolean isTerminal,
SqmCreationState creationState) {
- throw new PathException(
+ throw new UnknownPathException(
String.format(
Locale.ROOT,
"Static enum reference [%s#%s] cannot be de-referenced",
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java
index 8a9e52c6a5..5f26deb0af 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java
@@ -14,14 +14,13 @@ import java.util.List;
import java.util.Locale;
import org.hibernate.QueryException;
-import org.hibernate.query.PathException;
-import org.hibernate.query.SemanticException;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmExpressible;
+import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
@@ -229,7 +228,7 @@ public class SqmFieldLiteral implements SqmExpression, SqmExpressible,
String name,
boolean isTerminal,
SqmCreationState creationState) {
- throw new PathException(
+ throw new UnknownPathException(
String.format(
Locale.ROOT,
"Static field reference [%s#%s] cannot be de-referenced",
@@ -244,7 +243,7 @@ public class SqmFieldLiteral implements SqmExpression, SqmExpressible,
SqmExpression> selector,
boolean isTerminal,
SqmCreationState creationState) {
- throw new PathException(
+ throw new UnknownPathException(
String.format(
Locale.ROOT,
"Static field reference [%s#%s] cannot be de-referenced",
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/hql/ScrollableCollectionFetchingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/hql/ScrollableCollectionFetchingTest.java
index 9f84ab0cda..62659011ee 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/hql/ScrollableCollectionFetchingTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/hql/ScrollableCollectionFetchingTest.java
@@ -6,13 +6,16 @@
*/
package org.hibernate.orm.test.hql;
-import org.hibernate.HibernateException;
+import org.hibernate.Hibernate;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.dialect.AbstractHANADialect;
+import org.hibernate.dialect.DB2Dialect;
+import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.SybaseASEDialect;
-import org.hibernate.query.PathElementException;
+import org.hibernate.query.SemanticException;
+import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
@@ -43,22 +46,51 @@ import static org.junit.jupiter.api.Assertions.fail;
public class ScrollableCollectionFetchingTest {
@Test
- public void testTupleReturnFails(SessionFactoryScope scope) {
+ @SkipForDialect(dialectClass=DB2Dialect.class, matchSubTypes = true)
+ @SkipForDialect(dialectClass= DerbyDialect.class)
+ public void testTupleReturnWithFetch(SessionFactoryScope scope) {
+ scope.inTransaction(
+ session -> {
+ session.createMutationQuery("insert Mammal (description, bodyWeight, pregnant) values ('Human', 80.0, false)").executeUpdate();
+ assertEquals( 1L, session.createSelectionQuery("select count(*) from Mammal").getSingleResult() );
+ ScrollableResults results = session.createQuery("select a, a.bodyWeight from Animal a left join fetch a.offspring").scroll();
+ assertTrue( results.next() );
+ Object[] result = (Object[]) results.get();
+ assertTrue(Hibernate.isInitialized(((Animal) result[0]).getOffspring()));
+ session.createMutationQuery("delete Mammal").executeUpdate();
+ }
+ );
+ }
+
+ @Test
+ public void testTupleReturnWithFetchFailure(SessionFactoryScope scope) {
+ scope.inTransaction(
+ session -> {
+ try {
+ session.createQuery( "select a.description, a.bodyWeight from Animal a inner join fetch a.offspring" ).scroll();
+ fail( "scroll allowed with fetch and projection result" );
+ }
+ catch (IllegalArgumentException e) {
+ assertTyping( SemanticException.class, e.getCause() );
+ }
+ }
+ );
+ }
+
+
+ @Test
+ public void testUknownPathFailure(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
try {
session.createQuery( "select a, a.weight from Animal a inner join fetch a.offspring" ).scroll();
- fail( "scroll allowed with collection fetch and reurning tuples" );
+ fail( "scroll allowed with unknown path" );
}
catch (IllegalArgumentException e) {
- assertTyping( PathElementException.class, e );
- }
- catch (HibernateException e) {
- // expected result...
+ assertTyping( UnknownPathException.class, e.getCause() );
}
}
);
-
}
@Test