quarkus: Hibernate ORM 6.2 - NullPointerException in TupleMappingModelExpressible

Describe the bug

I am attempting to migrate from Quarkus 2.16.8 to 3.3.3 and I receive a NPE when running a query using the new version. Everything worked before and I thought I made all the necessary updates in the migration guide.

I’m assuming something is missing from my migration or configuration, but I can’t determine what.

Expected behavior

NullPointerException: Cannot invoke "org.hibernate.metamodel.mapping.MappingModelExpressible.forEachJdbcType(int, org.hibernate.internal.util.IndexedConsumer)
" because "this.components[i]" is null
        at org.hibernate.metamodel.model.domain.internal.TupleMappingModelExpressible.forEachJdbcType(TupleMappingModelExpressible.java:41)
        at org.hibernate.metamodel.model.domain.internal.TupleMappingModelExpressible.<init>(TupleMappingModelExpressible.java:28)
        at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.resolveMappingExpressible(MappingMetamodelImpl.java:810)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.determineValueMapping(BaseSqmToSqlAstConverter.java:5675)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.lambda$visitWithInferredType$98(BaseSqmToSqlAstConverter.java:6784)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.resolveInferredType(BaseSqmToSqlAstConverter.java:5216)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitTuple(BaseSqmToSqlAstConverter.java:5971)
        at org.hibernate.query.sqm.tree.expression.SqmTuple.accept(SqmTuple.java:84)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitWithInferredType(BaseSqmToSqlAstConverter.java:6786)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitInSubQueryPredicate(BaseSqmToSqlAstConverter.java:7716)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitInSubQueryPredicate(BaseSqmToSqlAstConverter.java:434)
        at org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate.accept(SqmInSubQueryPredicate.java:87)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitWhereClause(BaseSqmToSqlAstConverter.java:2471)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:2048)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:434)
        at org.hibernate.query.sqm.tree.select.SqmQuerySpec.accept(SqmQuerySpec.java:125)
        at org.hibernate.query.sqm.spi.BaseSemanticQueryWalker.visitQueryPart(BaseSemanticQueryWalker.java:221)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQueryPart(BaseSqmToSqlAstConverter.java:1902)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:1587)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:434)
        at org.hibernate.query.sqm.tree.select.SqmSelectStatement.accept(SqmSelectStatement.java:222)
        at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.translate(BaseSqmToSqlAstConverter.java:770)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:345)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:268)
        at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:244)
        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)
        at my.project.jpa.DataManager.getAll(DataManager.java:47)

Actual behavior

No failure

How to Reproduce?

Build Gradle:

dependencies {
    implementation 'io.quarkus:quarkus-config-yaml'
    implementation 'io.quarkus:quarkus-hibernate-orm'
    implementation 'io.quarkus:quarkus-jdbc-postgresql'
    implementation 'io.quarkus:quarkus-kubernetes'
    implementation 'io.quarkus:quarkus-kubernetes-config'
    implementation 'io.quarkus:quarkus-logging-json'
    implementation 'io.quarkus:quarkus-rest-client-reactive'
    implementation 'io.quarkus:quarkus-rest-client-reactive-jackson'
    implementation 'io.quarkus:quarkus-resteasy-reactive'
    implementation 'io.quarkus:quarkus-resteasy-reactive-jackson'
    implementation 'io.quarkus:quarkus-smallrye-context-propagation'
    implementation 'io.quarkus:quarkus-smallrye-health'
    implementation 'io.quarkus:quarkus-smallrye-openapi'
    implementation 'io.quarkus:quarkus-undertow'
    implementation 'org.amqphub.quarkus:quarkus-qpid-jms'
}

Code:

@Inject
private EntityManager em;

public List<MyEntity> getAll(final Instant time) {
    final TypedQuery<MyEntity> q = em.createNamedQuery(MyEntity.GET_LATEST_AT_TIME, MyEntity.class);
    q.setParameter("time", time);
    return q.getResultList();
}

@Entity
@Table(schema = "my_schema", name = "my_table")
@NamedQueries({
        @NamedQuery(name = MyEntity.GET_LATEST_AT_TIME,
                query = "SELECT m FROM MyEntity AS m WHERE (m.associatedId, m.value) IN"
                        + " (SELECT innerM.associatedId, max(innerM.value) FROM MyEntity AS innerM"
                        + " WHERE innerM.value <= :time AND innerM.isDeleted = false"
                        + " GROUP BY innerM.associatedId)")
})
public class MyEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final String GET_LATEST_AT_TIME = "my_table.getLatestAtTime";

    @Id
    @Column(name = "id")
    private UUID id;

    @Column(name = "value")
    private long value;

    @Column(name = "associated_id")
    private UUID associatedId;

    @Column(name = "is_deleted")
    private boolean isDeleted;
}

Config:

quarkus:
  datasource:
    db-kind: postgresql
    jdbc:
      background-validation-interval: 20S
      idle-removal-interval: 30S
      max-size: 10
      min-size: 0
      url: jdbc:postgresql://${PGHOST}:${PGPORT}/${PGDATABASE}?user=${PGDATABASE}&ApplicationName=my-project&reWriteBatchedInserts=true
    username: ${PGDATABASE}
    password: ${PGPASSWORD}

Output of uname -a or ver

No response

Output of java -version

Temurin 17.0.8

GraalVM version (if different from Java)

No response

Quarkus version or git rev

3.3.3

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 8.3

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Comments: 16 (7 by maintainers)

Most upvoted comments

I am experiencing the same bug in Spring Boot 3.1.4. The problem seems to be related to HQL queries containing clauses such as (value1, value2) IN (subquery). The “TupleMappingModelExpressible” constructor calls the “forEachJdbcType” method which uses the “components” array, but in this case, the array contains null values.

Thanks for letting us know @ingalemart! Did you report this to the ORM project already? Do you have a link?

Yes, here is the ticket: https://hibernate.atlassian.net/browse/HHH-17332

@yrodiere I added my entity class to the example. I don’t think it has to do with the query, I think that query is just the first one to be run.

@gsmet I’ll try to put together a self-contained reproducer. I’m not sure if I’ll be able to because of the postgres database though.