我在使用criteriaquery 时遇到了一些问题
我正在将一个基于Websphere(EAR(的服务器应用程序迁移到Spring引导。在这里,我需要使用DB2服务器上的存储过程来订购一个结果集。它在旧技术上运行得很好,但在spring-boot上失败了,因为两个框架之间创建的查询不同。
生成的旧查询(EAR(:
SELECT
t0.PURCHASE_ID, t0.USER, t0.CASH_AMT, ....
FN100_AMOUNT(ABS(t0.CASH_AMT), t1.CUR_NM_DECIMALS) AS SORTBY_AMOUNT
FROM
VG100_PURCHASES t0 LEFT OUTER JOIN
VG205_CURRENCIES t1 ON t0.CURRENCY= t1.CURRENCY_ID
WHERE (
t0.USER = ? AND
t0.PURCHASE_DATE = ?
)
ORDER BY
SORTBY_AMOUNT DESC
FETCH FIRST 10 ROWS ONLY
我使用criteriaQuery对其进行编码,将函数添加为Expression,设置别名,然后在order_by子句中引用它,如下所示:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Tuple> query = builder.createTupleQuery();
Root<Purchase> root = query.from(Purchase.class);
final Path<BigInteger> pathInt = root.get(Purchase_.cashAmount);
final Path<Integer> pathDec = root.join(Purchase_.currency, JoinType.LEFT)
.get(CurrencyEntity_.numberOfDecimals);
final Expression<BigDecimal> expression = builder.function("FN100_AMOUNT", BigDecimal.class,
builder.abs(pathInt), pathDec)
.as(BigDecimal.class);
Selection<BigDecimal> expressionAlias = expression.alias("SORTBY_AMOUNT");
// ... Add where clause
// Selected columns
final List<Selection<?>> selectList = ...
selectList.add(expressionAlias);
query.multiselect(selectList);
query.orderBy(builder.desc(root.get(expressionAlias.getAlias())));
//Order sort = builder.desc((Expression<?>) aliasSelection); // SAME ERROR
List<Tuple> resultList = em.createQuery(query).getResultList();
但是spring/hibernate生成的查询如下:
select
t0.purchase_id as col_0_0_,
t0.user as col_1_0_,
t0.cash_amt as col_2_0_, ...
FN100_AMOUNT(ABS(t0.cash_amt), t1.cur_nm_decimals) as col_17_0_
from
VG100_PURCHASES t0 LEFT OUTER JOIN
VG205_CURRENCIES t1 ON t0.CURRENCY= t1.CURRENCY_ID
where
t0.user = ? and
t0.purchase_date = ?
order by
FN100_AMOUNT(ABS(t0.cash_amt), t1.cur_nm_decimals) asc
fetch first 10 rows only;
DB2不接受这个查询,因为存储过程调用是在order_by子句中完成的,这里不允许,因为它必须在select子句中完成。
如果我发送最终所需的查询,它可以毫无问题地工作。旧框架(OpenJPA(正确地使用了别名。
所以问题是,如何使用条件查询使别名正常工作
如果需要,询问任何缺失的细节
谢谢!
额外信息
项目中使用的部门:
- 冬眠-核心-5.2.14
- 弹簧靴2.0.0
- 春季数据jpa 2.0.5
在Hibernate 6之前,当使用JPA Criteria API时,不可能在order by子句中引用别名。您只能通过使用HQL/JPQL来做到这一点。