Compilation Error Using CriteriaBuilder

I am trying to convert this JPA QL to a criteria builder. JBoss 6.0.

"SELECT ba FROM BankAccount ba WHERE ba.balance >= :amt ORDER BY ba.ownerName ASC"

I wrote this code according to several tutorials.

public List<BankAccount> findWithBalance(int amount) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class);
    Root<BankAccount> from = cq.from(BankAccount.class);

    ParameterExpression<Integer> balance = cb.parameter(Integer.class);
    cq.select(from);

    Predicate predicate = cb.gt(from.get("balance"), balance);
    cq.where(predicate);

    cq.orderBy(cb.asc(from.get("ownerName")));

    TypedQuery<BankAccount> query = em.createQuery(cq);

    return query.getResultList();
}

But I get a compilation error in the line:

Predicate predicate = cb.gt(from.get("balance"), balance);

Mistake:

The method gt(Expression<? extends Number>, Expression<? extends Number>) in the type CriteriaBuilder is not applicable for the arguments (Path<Object>, ParameterExpression<Integer>)
+3
source share
3 answers

Well, finally, I found the correct way to call the gt () method. Here is the complete solution. Fully tested in JBoss 6.

public List<BankAccount> findWithBalance(int amount) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class);
    Root<BankAccount> from = cq.from(BankAccount.class);

    ParameterExpression<Integer> balance = cb.parameter(Integer.class);
    cq.select(from);

    //Here is the trick!
    Predicate predicate = cb.gt(from.<Integer> get("balance"), balance);

    cq.where(predicate);
    cq.orderBy(cb.asc(from.get("ownerName")));

    TypedQuery<BankAccount> query = em.createQuery(cq);

    query.setParameter(balance, amount);

    return query.getResultList();
}
+10
source

The type security function in JPA restricts such comparisons to incompatible types, the compiler will throw an error.

It from.get("balance")returns here Path<Object>, but the method can accept a type parameter java.lang.Number, therefore it leads to an error.

You can try the code below.

//--
    Metamodel metamodel = em.getMetamodel();
    EntityType<BankAccount> pClass = metamodel.entity(BankAccount.class);
    Predicate predicate = cb.gt(from.get(pClass.getSingularAttribute("balance", Integer.class)), balance);
//--

Metamodel API, , ClassName_.field cb.gt(from.get(BankAccount_.balance), balance), .

, , JPA .

+3

, amount - int, Expression, , , Expression , .

0

Source: https://habr.com/ru/post/1523415/


All Articles