Disallow FQN as entity name in Jpa compliance mode

This commit is contained in:
Nathan Xu 2020-02-02 16:06:51 -05:00 committed by Steve Ebersole
parent c97fb45a02
commit 60ead26c4b
3 changed files with 58 additions and 3 deletions

View File

@ -167,7 +167,6 @@
import static org.hibernate.grammars.hql.HqlParser.IDENTIFIER; import static org.hibernate.grammars.hql.HqlParser.IDENTIFIER;
import static org.hibernate.query.TemporalUnit.*; import static org.hibernate.query.TemporalUnit.*;
import static org.hibernate.type.descriptor.DateTimeUtils.DATE_TIME; 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; import static org.hibernate.type.spi.TypeConfiguration.isJdbcTemporalType;
/** /**
@ -264,7 +263,7 @@ else if ( ctx.deleteStatement() != null ) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// To-level statements // Top-level statements
@Override @Override
public SqmSelectStatement visitSelectStatement(HqlParser.SelectStatementContext ctx) { public SqmSelectStatement visitSelectStatement(HqlParser.SelectStatementContext ctx) {
@ -828,7 +827,7 @@ public EntityDomainType<?> visitEntityName(HqlParser.EntityNameContext parserEnt
if ( entityReference == null ) { if ( entityReference == null ) {
throw new UnknownEntityException( "Could not resolve entity name [" + entityName + "] as DML target", entityName ); throw new UnknownEntityException( "Could not resolve entity name [" + entityName + "] as DML target", entityName );
} }
checkFQNEntityNameJpaComplianceViolationIfNeeded( entityName, entityReference );
return entityReference; return entityReference;
} }
@ -895,6 +894,8 @@ public SqmRoot visitPathRoot(HqlParser.PathRootContext ctx) {
name name
); );
checkFQNEntityNameJpaComplianceViolationIfNeeded( name, entityDescriptor );
if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) { if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) {
if ( getCreationOptions().useStrictJpaCompliance() ) { if ( getCreationOptions().useStrictJpaCompliance() ) {
throw new StrictJpaComplianceViolation( throw new StrictJpaComplianceViolation(
@ -3510,4 +3511,14 @@ public void addDowncast(
throw new NotYetImplementedFor6Exception(); 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
);
}
}
} }

View File

@ -26,6 +26,7 @@ public enum Type {
SUBQUERY_ORDER_BY( "use of ORDER BY clause in subquery" ), SUBQUERY_ORDER_BY( "use of ORDER BY clause in subquery" ),
LIMIT_OFFSET_CLAUSE( "use of LIMIT/OFFSET clause" ), 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" ), 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; private final String description;

View File

@ -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() ) );
}
}