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 2d151cc02f..4edb797a14 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 @@ -167,7 +167,6 @@ import static java.util.Collections.singletonList; import static org.hibernate.grammars.hql.HqlParser.IDENTIFIER; import static org.hibernate.query.TemporalUnit.*; import static org.hibernate.type.descriptor.DateTimeUtils.DATE_TIME; -import static org.hibernate.type.descriptor.DateTimeUtils.OFFSET_DATE_TIME; import static org.hibernate.type.spi.TypeConfiguration.isJdbcTemporalType; /** @@ -264,7 +263,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // To-level statements + // Top-level statements @Override public SqmSelectStatement visitSelectStatement(HqlParser.SelectStatementContext ctx) { @@ -828,7 +827,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre if ( entityReference == null ) { throw new UnknownEntityException( "Could not resolve entity name [" + entityName + "] as DML target", entityName ); } - + checkFQNEntityNameJpaComplianceViolationIfNeeded( entityName, entityReference ); return entityReference; } @@ -895,6 +894,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre name ); + checkFQNEntityNameJpaComplianceViolationIfNeeded( name, entityDescriptor ); + if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) { if ( getCreationOptions().useStrictJpaCompliance() ) { throw new StrictJpaComplianceViolation( @@ -3510,4 +3511,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre throw new NotYetImplementedFor6Exception(); } } + + private void checkFQNEntityNameJpaComplianceViolationIfNeeded(String name, EntityDomainType entityDescriptor) { + if ( getCreationOptions().useStrictJpaCompliance() && ! name.equals( entityDescriptor.getName() ) ) { + // FQN is the only possible reason + throw new StrictJpaComplianceViolation("Encountered FQN entity name [" + name + "], " + + "but strict JPQL compliance was requested ( [" + entityDescriptor.getName() + "] should be used instead )", + StrictJpaComplianceViolation.Type.FQN_ENTITY_NAME + ); + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/StrictJpaComplianceViolation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/StrictJpaComplianceViolation.java index 89a53143c0..d50ea16af4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/StrictJpaComplianceViolation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/StrictJpaComplianceViolation.java @@ -26,6 +26,7 @@ public class StrictJpaComplianceViolation extends SemanticException { SUBQUERY_ORDER_BY( "use of ORDER BY clause in subquery" ), LIMIT_OFFSET_CLAUSE( "use of LIMIT/OFFSET clause" ), IDENTIFICATION_VARIABLE_NOT_DECLARED_IN_FROM_CLAUSE( "use of an alias not declared in the FROM clause" ), + FQN_ENTITY_NAME( "use of FQN for entity name" ), ; private final String description; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/JpaComplianceDisallowFQNTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/JpaComplianceDisallowFQNTests.java new file mode 100644 index 0000000000..ff89606111 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/JpaComplianceDisallowFQNTests.java @@ -0,0 +1,43 @@ +package org.hibernate.orm.test.query.hql; + +import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest; +import org.hibernate.orm.test.query.sqm.domain.Person; +import org.hibernate.query.sqm.StrictJpaComplianceViolation; +import org.hibernate.testing.orm.junit.ExpectedException; +import org.junit.jupiter.api.Test; + +/** + * @author Nahtan Xu + */ +@SuppressWarnings("WeakerAccess") +public class JpaComplianceDisallowFQNTests extends BaseSqmUnitTest { + + @Override + protected boolean strictJpaCompliance() { + return true; + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Person.class }; + } + + @Test + @ExpectedException(StrictJpaComplianceViolation.class) + public void testQuery() { + interpretSelect( String.format( "select p from %s p", Person.class.getName() ) ); + } + + @Test + @ExpectedException(StrictJpaComplianceViolation.class) + public void testUpdate() { + interpretSelect( String.format( "update %s set numberOfToes = 0", Person.class.getName() ) ); + } + + @Test + @ExpectedException(StrictJpaComplianceViolation.class) + public void testDelete() { + interpretSelect( String.format( "delete %s", Person.class.getName() ) ); + } + +}