HHH-15433 Return a literal for Path#type when no discriminator exists

This commit is contained in:
Christian Beikov 2022-08-04 10:14:27 +02:00
parent a69912dd9c
commit f8eb133334
2 changed files with 34 additions and 1 deletions

View File

@ -18,6 +18,8 @@ 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.sqm.SqmExpressible;
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
@ -137,7 +139,18 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public SqmExpression<Class<? extends T>> type() { public SqmExpression<Class<? extends T>> type() {
return (SqmExpression<Class<? extends T>>) get( EntityDiscriminatorMapping.ROLE_NAME ); final SqmPathSource<T> referencedPathSource = getReferencedPathSource();
final SqmPathSource<?> subPathSource = referencedPathSource.findSubPathSource( EntityDiscriminatorMapping.ROLE_NAME );
if ( subPathSource == null ) {
return new SqmLiteral<>(
referencedPathSource.getBindableJavaType(),
(SqmExpressible<? extends Class<? extends T>>) (SqmExpressible<?>) nodeBuilder().getTypeConfiguration()
.getBasicTypeForJavaType( Class.class ),
nodeBuilder()
);
}
return (SqmExpression<Class<? extends T>>) resolvePath( EntityDiscriminatorMapping.ROLE_NAME, subPathSource );
} }
@Override @Override

View File

@ -13,10 +13,12 @@ import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.Root;
import org.hibernate.orm.test.jpa.metamodel.AbstractMetamodelSpecificTest; import org.hibernate.orm.test.jpa.metamodel.AbstractMetamodelSpecificTest;
import org.hibernate.orm.test.jpa.metamodel.Address;
import org.hibernate.orm.test.jpa.metamodel.Order; 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.testing.TestForIssue;
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;
@ -120,4 +122,22 @@ public class AbstractPathImplTest extends AbstractMetamodelSpecificTest {
em.close(); em.close();
} }
} }
@Test
@TestForIssue( jiraKey = "HHH-15433")
public void testTypeExpressionWithoutInheritance() {
EntityManager em = getOrCreateEntityManager();
try {
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Address> criteria = criteriaBuilder.createQuery( Address.class );
Root<Address> addressRoot = criteria.from( Address.class );
criteria.select( addressRoot );
criteria.where( criteriaBuilder.equal( addressRoot.type(), criteriaBuilder.literal( Address.class ) ) );
em.createQuery( criteria ).getResultList();
}
finally {
em.close();
}
}
} }