查询中带有 Jpa 3.1 实例化的 Spring Boot 3.0 不起作用

问题描述 投票:0回答:3

自从升级到 Spring Boot 3.0 后,以下查询不再起作用:

   @Query("""
        select new com.example.OrderProductWithAmount(
            op, sum(op.amount), sum(op.paidAmount)
        )
        from OrderProduct op
        join op.order o join op.product p join o.table t
        where t.id = :tableId group by p.id
        """)
    fun getAllSummarizedByTableId(@Param("tableId") tableId: Long): List<OrderProductWithAmount>
data class OrderProductWithAmount(
    val orderProduct: OrderProduct,
    val amount: Int,
    val paidAmount: Int
) {
    constructor(
        orderProduct: OrderProduct,
        amount: Long,
        paidAmount: Long
    ) : this(
        orderProduct,
        amount.toInt(),
        paidAmount.toInt()
    )
}

@Entity
@jakarta.persistence.Table(name = "order_product")
data class OrderProduct(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long = -1,

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id", nullable = false)
    var order: Order,

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id", nullable = false)
    var product: Product,

    @Column(name = "amount", nullable = false)
    var amount: Int,

    @Column(name = "paid_amount", nullable = false)
    var paidAmount: Int = 0,
)

日志:

Error performing dynamic instantiation : com.example.OrderProductWithAmount
org.springframework.orm.jpa.JpaSystemException: Error performing dynamic instantiation : com.example.OrderProductWithAmount
Caused by: org.hibernate.query.sqm.sql.internal.InstantiationException: Error performing dynamic instantiation : com.example.OrderProductWithAmount
    at app//org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationAssemblerConstructorImpl.assemble(DynamicInstantiationAssemblerConstructorImpl.java:58)
    at app//org.hibernate.sql.results.internal.StandardRowReader.readRow(StandardRowReader.java:104)
    at app//org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:198)
    at app//org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:33)
    at app//org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:443)
    at app//org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:166)
    at app//org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.list(JdbcSelectExecutorStandardImpl.java:91)
    at app//org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:31)
    at app//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.lambda$new$0(ConcreteSqmSelectQueryPlan.java:113)
    at app//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:335)
    at app//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:276)
    at app//org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:571)
    at app//org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:363)
    at app//org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:1073)
    at app//org.hibernate.query.Query.getResultList(Query.java:94)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at [email protected]/java.lang.reflect.Method.invoke(Method.java:568)
    at app//org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:401)
    at app/jdk.proxy3/jdk.proxy3.$Proxy231.getResultList(Unknown Source)
    at app//org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:127)
    at app//org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:90)
    at app//org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:148)
    at app//org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:136)
    at app//org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
    at app//org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
    at app//org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
    at app//org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
    at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at app//org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:77)
    at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at app//org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at app//org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at app//org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
    at app//org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    ... 104 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiationAssemblerConstructorImpl.assemble(DynamicInstantiationAssemblerConstructorImpl.java:52)
    ... 140 more

是否不再可能像我使用

op
那样传递整个数据库对象?

spring-boot jpa spring-data-jpa spring-data spring-kotlin
3个回答
1
投票
当应用于整数类型的状态字段(

SUM

除外)时,
Long
返回
BigInteger
Double
应用于浮点类型的状态字段时;
BigInteger
当应用于
BigInteger
类型的状态字段时;和
BigDecimal
当应用于
BigDecimal
类型的状态字段时。

这来自 JPA 3.1 规范

所以它应该返回一个

Long
。我怀疑它会被数据类中的构造函数混淆。如果将类型从
Int
更改为
Long
并删除附加构造函数,会发生什么?


0
投票

你的sql看起来有问题,尝试更改为以下内容

自从升级到 Spring Boot 3.0 后,以下查询不再起作用:

  @Query("""
        select new com.example.OrderProductWithAmount(
            op, sum(op.amount), sum(op.paidAmount)
        )
        from OrderProduct op
        where op.id = :tableId group by op.id
        """)

我没有看到你有t表和p表关联查询 @kaulex


0
投票

在我的例子中,我创建了一个具有三个默认参数(JPQL 查询中使用的参数)的构造函数,并将所有数字字段设置为 Long。

© www.soinside.com 2019 - 2024. All rights reserved.