Compile error when using CriteriaBuilder

后端 未结 3 1914
-上瘾入骨i
-上瘾入骨i 2021-01-19 10:13

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

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


        
相关标签:
3条回答
  • 2021-01-19 10:45

    Well, I finally found the right 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();
    }
    
    0 讨论(0)
  • 2021-01-19 10:49

    The type safety feature in JPA restricts such comparisons with incompatible types, the compiler itself will raise error.

    Here, from.get("balance") returns the Path<Object>, but the method can accept parameter of type java.lang.Number, therefore results in error.

    You can try the below code.

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

    If you are using Metamodel API, then you can retieve directly by specifying ClassName_.field as cb.gt(from.get(BankAccount_.balance), balance) which is much cleaner & easy to debug.

    But if you are having many entities, then it may be difficult to write their Metamodel classes manually, if the JPA provider doesn't generate them.

    0 讨论(0)
  • 2021-01-19 10:53

    The compiler is complaining because amount is an int, not an Expression, see if you can figure out how to build an Expression that's a constant and use that and you should be good.

    0 讨论(0)
提交回复
热议问题