Correct usage of JPA criteria API, Predicates and where method of CriteriaQuery

寵の児 提交于 2019-11-30 04:03:12

Starting from your hint in the final part of your post, I agree that the way you are adding predicates for the where clause is not correct.

I see two ways of proceeding:

First way

Using an array of predicates

List<Predicate> predicates = new ArrayList<Predicate>();
for (Key key : keys) {
    predicates.add(criteriaBuilder.equal(root.get(key), value));
}
c.where(criteriaBuilder.and(predicates.toArray(new Predicate[] {})));

Second way

Modifying the same predicate in the loop

Predicate predicate = criteriaBuilder.conjunction();
for (Key key : keys) {
    Predicate newPredicate = criteriaBuilder.equal(root.get(key), value);
    predicate = criteriaBuilder.and(predicate, newPredicate);
}
c.where(predicate);

EDITED

After looking again your code sample, I see that you have already created in the correct way a list of PredicateS: you have called it criteria. You are only using them in the wrong way. See the last line of my first example.


EDIT 2

In order to see if the problem is generated by the use of PredicateExpressionS, that are not specifically needed in your case, try to temporarily remove them. Modify your first criteria from

if (identifiant != null && !identifiant.trim().equals("")) {
    ParameterExpression<String> parameter = criteriaBuilder.parameter(String.class, "identifiant");
    Predicate condition = criteriaBuilder.like(boite.<String> get("identifiant"), parameter);
    criteria.add(condition);
}

to

if (identifiant != null && !identifiant.trim().equals("")) {
    Predicate condition = criteriaBuilder.like(boite.get("identifiant"), "%" + identifiant + "%");
    criteria.add(condition);
}

The complete solution that work for me is the following:

        CriteriaBuilder builder = session.getCriteriaBuilder();
        CriteriaQuery<Object[]> criteriaQuery = builder.createQuery(Object[].class);
        Root<Eje> ejeRoot = criteriaQuery.from(Eje.class);
        Root<FactorCritico> factorRoot = criteriaQuery.from(FactorCritico.class);


        int factorParam = 2;

        criteriaQuery.multiselect(ejeRoot,factorRoot);

        List<Predicate> predicates = new ArrayList<>();

        Predicate ejeJoinFactorCritico = builder.equal(ejeRoot.get("id"), factorRoot.get("eje"));
        predicates.add(ejeJoinFactorCritico);   

        if (factorParam> 0){
            Predicate factorFilter = builder.equal(factorRoot.get("id"), factorParam);
            predicates.add(factorFilter);   
        }

        criteriaQuery.where(builder.and(predicates.toArray(new Predicate[] {})));

        Query<Object[]> query = session.createQuery(criteriaQuery);
        List<Object[]> resultList = query.getResultList();

        for(Object[] objects: resultList){
            Eje eje = (Eje) objects[0];
            System.out.println("eje: "+eje.getName());

            FactorCritico factor= (FactorCritico) objects[1];
            System.out.println("--> factor: "+factor.getName()+ ", eje: "+ factor.getEje().getName());

            //System.out.println("eje, factor size = "+eje.getFactorCriticos());
        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!