After the migration to Quarkus 3.14 and Hibernate 6, custom query projections stopped working.
I have many more examples but all comes to this exception and combination of a custom query and an aggregate class projection.
The exception I get:
org.hibernate.InstantiationException: Cannot instantiate query result type 'xx.domain.UnitDetails' due to: xx.domain.BusinessUnitDetails.<init>(java.lang.String,xx.domain.BusinessUnitType,java.lang.Integer)
at org.hibernate.sql.results.internal.RowTransformerConstructorImpl.<init>(RowTransformerConstructorImpl.java:42)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.determineRowTransformer(ConcreteSqmSelectQueryPlan.java:315)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.<init>(ConcreteSqmSelectQueryPlan.java:96)
at org.hibernate.query.sqm.internal.AbstractSqmSelectionQuery.buildConcreteQueryPlan(AbstractSqmSelectionQuery.java:277)
at org.hibernate.query.sqm.internal.AbstractSqmSelectionQuery.buildConcreteQueryPlan(AbstractSqmSelectionQuery.java:261)
at org.hibernate.query.sqm.internal.AbstractSqmSelectionQuery.buildSelectQueryPlan(AbstractSqmSelectionQuery.java:247)
at org.hibernate.query.internal.QueryInterpretationCacheStandardImpl.resolveSelectQueryPlan(QueryInterpretationCacheStandardImpl.java:83)
at org.hibernate.query.sqm.internal.SqmSelectionQueryImpl.resolveQueryPlan(SqmSelectionQueryImpl.java:371)
at org.hibernate.query.sqm.internal.SqmSelectionQueryImpl.doList(SqmSelectionQueryImpl.java:298)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:136)
at org.hibernate.query.SelectionQuery.getResultList(SelectionQuery.java:124)
at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.list(CommonPanacheQueryImpl.java:303)
at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.list(PanacheQueryImpl.java:150)
at xx.persistence.repository.route.RouteRepository.getSender(RouteRepository.kt:111)
at xx.persistence.repository.route.RouteRepository_Subclass.getSender$superforward(Unknown Source)
at xx.persistence.repository.route.RouteRepository_Subclass$function$26.apply(Unknown Source)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:136)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:107)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:38)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:61)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:32)
at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
at xx.persistence.repository.route.RouteRepository_Subclass.getSender(Unknown Source)
at xx.persistence.repository.route.RouteRepository_ClientProxy.getSender(Unknown Source)
at xx.repository.route.RouteRepositoryIntegrationTest.should return a list of active consignees for the given consignor when one matching consignor(RouteRepositoryIntegrationTest.kt:182)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:973)
at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:823)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.NoSuchMethodException: xx.domain.BusinessUnitDetails.<init>(java.lang.String,xx.BusinessUnitType,java.lang.Integer)
at java.base/java.lang.Class.getConstructor0(Class.java:3641)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2810)
at org.hibernate.sql.results.internal.RowTransformerConstructorImpl.<init>(RowTransformerConstructorImpl.java:37)
... 34 more
Repository layer, script:
fun getSender(senderId: Long): UnitDetails {
return find(
"SELECT ud.code, ud.type, route.sequence " +
"FROM RouteEntity route " +
"JOIN UnitDetailsEntity ud ON ud.id = route.senderUnitDetailsId "
).project(UnitDetails::class.java).list()
}
The aggregate class I use to project with a custom constructor to satisfy hibernate:
class UnitDetails(
val businessUnit: BusinessUnit,
val sequence: Int
) {
constructor(
code: String,
type: BusinessUnitType,
sequence: Int
) : this(BusinessUnit(code, type), sequence)
}