我试图使用QueryDSL进行Coalesce而没有任何运气。
这是我想要做的:我有一些Order
个对象,它们有OrderItem
个对象。每个OrderItem
都有一个价格(BigDecimal)。对于每个Order
,我希望在元组中返回Order
的ID以及OrderItem
价格的总和。我的模型和我的查询实际上比这更复杂,因此,我必须在子查询中进行求和。
这是我写的:
NumberSubQuery<BigDecimal> sumQuery = new HibernateSubQuery()
.from(qOrderItem)
.where(qOrderItem.order.eq(qOrder))
.unique(qOrderItem.price.sum());
HibernateQuery query = new HibernateQuery(session).from(qOrder)
.list(new QOrderTuple(qOrder.id, sumQuery))
OrderTuple
是一个仅包含两个字段的元组:id(long)和priceSum(BigDecimal)。
我写的查询工作正常。现在,我想确保如果Order
没有OrderItem
,那么sumQuery
会返回0(而不是null
,就像现在一样)。因此我修改了我的子查询如下:
NumberSubQuery<BigDecimal> sumQuery = new HibernateSubQuery()
.from(qOrderItem)
.where(qOrderItem.order.eq(qOrder))
.unique(qOrderItem.price.sum().coalesce(BigDecimal.ZERO));
问题是此代码无法编译,因为unique()
返回的类型现在是SimpleSubQuery<BigDecimal>
。但是,QOrderTuple
的构造函数需要NumberExpression<? extends BigDecimal>
,而不是SimpleSubQuery<BigDecimal>
。
我还尝试向asNumber()
添加coalesce()
,但我得到了NumberExpression<?>
,构造函数也不接受它。最后,我尝试使用显式Java强制转换来编译代码,但它在运行时失败了:
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysema.query.types.ConstructorExpression.newInstance(ConstructorExpression.java:131)
at com.mysema.query.jpa.FactoryExpressionTransformer.transformTuple(FactoryExpressionTransformer.java:50)
at org.hibernate.hql.HolderInstantiator.instantiate(HolderInstantiator.java:96)
at org.hibernate.impl.ScrollableResultsImpl.prepareCurrentRow(ScrollableResultsImpl.java:268)
at org.hibernate.impl.ScrollableResultsImpl.next(ScrollableResultsImpl.java:123)
我是否在使用合并语法时出错?
提前致谢