@Query("""
SELECT new com.acme.PaymentReferenceItem(com.acme.PaymentReferenceItem$Type.TRANSACTION, e.id, e.reference) \
FROM Transaction e WHERE e.reference IN :references UNION ALL \
SELECT new com.acme.PaymentReferenceItem(com.acme.PaymentReferenceItem$Type.DIRECT_DEBIT, e.id, e.reference) \
FROM DirectDebit e WHERE e.reference IN :references UNION ALL \
SELECT new com.acme.PaymentReferenceItem(com.acme.PaymentReferenceItem$Type.DIRECT_DEBIT_GROUP, e.id, e.reference) \
FROM DirectDebitGroup e WHERE e.reference IN :references
""")
Set<PaymentReferenceItem> findExistingReferences(Set<String> references);
where the enum is
public record PaymentReferenceItem(Type type, Long id, String reference) {
public enum Type {
TRANSACTION, DIRECT_DEBIT_GROUP, DIRECT_DEBIT
}
}
Worked as expected on 6.5.3. The PaymentReferenceItem$Type was considered a SqmEnumLiteral while doing conversion.
But now with Hibernate 6.6.2 it causes the exception Could not determine ValueMapping for SqmExpression: org.hibernate.query.sqm.tree.expression.SqmFieldLiteral on BaseSqmToSqlAstConverter.
I tried debugging but couldn’t figure out why it’s no longer considered a SqmEnumLiteral. Any ideas?
Hello @samba, your query looks fine to me, especially since you say it worked in a previous version - could you please also try with the more recent 6.6.3?
If the issue persists, this is probably caused by a bug - please try to create a reproducer with our test case template and if you are able to reproduce the issue, create a new ticket in our issue tracker and attach that reproducer.
Thanks for your reply @mbladel . Tried with 6.6.3 but had the same issue. Seems to happen consistently where a literal enum is used with a constructor in HQL, like SELECT new com.acme.MyClass(com.acme.MyEnum.VALUE, e.arg2, e.arg3...) FROM MyEntity e.
For completeness I’ll add the stacktrace that I missed in my original post:
Caused by: org.hibernate.query.sqm.sql.ConversionException: Could not determine ValueMapping for SqmExpression: org.hibernate.query.sqm.tree.expression.SqmFieldLiteral@3da82e6a
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.determineValueMapping(BaseSqmToSqlAstConverter.java:6088)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.determineValueMapping(BaseSqmToSqlAstConverter.java:5965)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitFieldLiteral(BaseSqmToSqlAstConverter.java:7361)
at org.hibernate.query.sqm.tree.expression.SqmFieldLiteral.accept(SqmFieldLiteral.java:139)
at org.hibernate.query.sqm.tree.select.SqmDynamicInstantiationArgument.accept(SqmDynamicInstantiationArgument.java:57)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitDynamicInstantiation(BaseSqmToSqlAstConverter.java:1656)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitDynamicInstantiation(BaseSqmToSqlAstConverter.java:454)
at org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation.accept(SqmDynamicInstantiation.java:254)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelection(BaseSqmToSqlAstConverter.java:2270)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectClause(BaseSqmToSqlAstConverter.java:2212)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:2083)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:454)
at org.hibernate.query.sqm.tree.select.SqmQuerySpec.accept(SqmQuerySpec.java:124)
at org.hibernate.query.sqm.spi.BaseSemanticQueryWalker.visitQueryPart(BaseSemanticQueryWalker.java:245)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQueryPart(BaseSqmToSqlAstConverter.java:1943)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:1629)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:454)
at org.hibernate.query.sqm.tree.select.SqmSelectStatement.accept(SqmSelectStatement.java:238)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.translate(BaseSqmToSqlAstConverter.java:800)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:482)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:388)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:362)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:380)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:143)
at org.hibernate.query.Query.getResultList(Query.java:120)
Once again, please create an issue in our tracker and attach a simple reproducer test case so that someone from the Hibernate team can take a look and try to fix this issue, thanks.
@DomainModel(annotatedClasses = Transaction.class)
@SessionFactory
public class Test10672 {
@Test
void test(SessionFactoryScope scope) {
scope.fromSession( em ->
em.createQuery( """
SELECT new org.hibernate.bugs.PaymentReferenceItem(org.hibernate.bugs.PaymentReferenceItem$Type.TRANSACTION, e.id, e.reference) \
FROM Transaction e WHERE e.reference IN :references""", PaymentReferenceItem.class )
.setParameter( "references", List.of( "abc" ) )
.getResultList() );
}
}
@Entity
class Transaction {
@Id
Long id;
String reference;
}
record PaymentReferenceItem(Type type, Long id, String reference) {
public enum Type {
TRANSACTION, DIRECT_DEBIT_GROUP, DIRECT_DEBIT
}
}
I’ve simplified example above (DTO class is not needed to make it fail) and created possible solution proposal - Jira issue HHH-18894 and pull request #9342