Hello, Starting in Hibernate v6.2.3, I’ve got a regression on criteria queries when the root of the query is the child and the selection contains a field of the parent and a field of a junction of the child.
The junction on the parent table is missing in the generated query.
Considering the following entities:
{code:java}@Entity @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING) public abstract class AbstractParent {
@Id @Column(columnDefinition = "uuid") private final UUID id = UUID.randomUUID();
@Column private String name; }
@Entity @DiscriminatorValue("CHILD") public class Child extends AbstractParent {
@OneToMany(mappedBy = "child") private final List<Attribute> attributeList = new ArrayList<>(); }
@Entity public class Attribute {
@Id @Column(columnDefinition = "uuid") private final UUID id = UUID.randomUUID();
@ManyToOne @JoinColumn private Child child;
@Column private String attributeName name ; }{code}
The following test fails with Hibernate 6.2.3 (and later) while it worked on v6.2.2
{noformat} @Test @Transactional void testHibernate6_2_3() { final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); final CriteriaQuery<Tuple> query = builder.createTupleQuery();
final Root<Child> child = query.from(Child.class); final Join<Child, Attribute> attributes = child.join("attributeList", JoinType.LEFT);
// Get a field of the parent final Expression<String> parentName = child.get("name");
// Get a field of the joined attribute final Expression<String> attributeName = attributes.get("name");
query.multiselect(parentName, attributeName); entityManager.createQuery(query).getResultList(); }{noformat}
The given error is
{noformat}org.hibernate.exception.SQLGrammarException: could not prepare statement [Column "C1_1.NAME" not found Column "C1_1.NAME" not found; SQL statement: select c1_1.name,a1_0.name from child c1_0 left join attribute a1_0 on c1_0.id=a1_0.child_id [42122-214]] [select c1_1.name,a1_0.name from child c1_0 left join attribute a1_0 on c1_0.id=a1_0.child_id] at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:64) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:56) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:187) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareStatement(StatementPreparerImpl.java:76) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.lambda$list$0(JdbcSelectExecutorStandardImpl.java:102) at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:226) at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.getResultSet(DeferredResultSetAccess.java:163) at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.advanceNext(JdbcValuesResultSetImpl.java:204) at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.processNext(JdbcValuesResultSetImpl.java:84) at org.hibernate.sql.results.jdbc.internal.AbstractJdbcValues.next(AbstractJdbcValues.java:29) at org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.next(RowProcessingStateStandardImpl.java:66) at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:198) at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:33) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:361) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:168) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.list(JdbcSelectExecutorStandardImpl.java:93) at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:31) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$0(ConcreteSqmSelectQueryPlan.java:109) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:302) at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:243) at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:518) at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:367) at org.hibernate.query.Query.getResultList(Query.java:119) {noformat}
We can see that in the generated query, the join on “parent” table is missing
{code:sql}select c1_1.name, a1_0.name from child c1_0 // missing [inner join parent c1_1 on c1_0.id=c1_1.id] left join attribute a1_0 on c1_0.id=a1_0.child_id{code} |
|