Home > Back-end >  Why alias is not working on criteriaQuery
Why alias is not working on criteriaQuery

Time:09-30

I'm facing some troubles using criteriaquery

I'm migrating a server app based on Websphere (EAR) to Spring-boot. Here I need to order a result set using a stored procedure on a DB2 server. It works perfect on the old tecnology but fails on spring-boot as the created query differs between both frameworks.

Generated old query (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 

I'm coding it using criteriaQuery, adding the function as an Expression, setting an alias, then referencing it in the order_by clause, as follows:

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();

But the spring/hibernate generated query is as follows:

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;

This query is not accepted by DB2 as the stored procedure call is done inside the order_by clause, not allowed here as it must be done in the select clause.

If I send the final desired query it works without any problem. Old framework (OpenJPA) correctly uses aliases.

So the question is, how can I get alias working properly using criteria query?

Ask for any missing detail if needed

Thank you!

Extra info

Depencencies used in the project:

  • hibernate-core-5.2.14
  • spring-boot 2.0.0
  • spring-data-jpa 2.0.5

CodePudding user response:

Prior to Hibernate 6 it wasn't possible to refer to aliases in the order by clause when using the JPA Criteria API. You can only do that by using HQL/JPQL.

  • Related