Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA/Criteria API - Like & equal problem

I'm trying to use Criteria API in my new project:

public List<Employee> findEmps(String name) {     CriteriaBuilder cb = em.getCriteriaBuilder();     CriteriaQuery<Employee> c = cb.createQuery(Employee.class);     Root<Employee> emp = c.from(Employee.class);     c.select(emp);     c.distinct(emp);     List<Predicate> criteria = new ArrayList<Predicate>();      if (name != null) {         ParameterExpression<String> p = cb.parameter(String.class, "name");         criteria.add(cb.equal(emp.get("name"), p));     }      /* ... */      if (criteria.size() == 0) {         throw new RuntimeException("no criteria");     } else if (criteria.size() == 1) {         c.where(criteria.get(0));     } else {         c.where(cb.and(criteria.toArray(new Predicate[0])));     }      TypedQuery<Employee> q = em.createQuery(c);      if (name != null) {         q.setParameter("name", name);     }      /* ... */      return q.getResultList(); } 

Now when I change this line:

            criteria.add(cb.equal(emp.get("name"), p)); 

to:

            criteria.add(cb.like(emp.get("name"), p)); 

I get an error saying:

The method like(Expression, Expression) in the type CriteriaBuilder is not > applicable for the arguments (Path, ParameterExpression)

What's the problem?

like image 211
John Manak Avatar asked Oct 25 '10 12:10

John Manak


People also ask

What is JPA Criteria API?

Advertisements. The Criteria API is a predefined API used to define queries for entities. It is the alternative way of defining a JPQL query. These queries are type-safe, and portable and easy to modify by changing the syntax.

Is Criteria API deprecated?

The Criteria API allows us to build up a criteria query object programmatically, where we can apply different kinds of filtration rules and logical conditions. Since Hibernate 5.2, the Hibernate Criteria API is deprecated, and new development is focused on the JPA Criteria API.

What is a criteria API?

The Criteria API is used to define queries for entities and their persistent state by creating query-defining objects. Criteria queries are written using Java programming language APIs, are typesafe, and are portable. Such queries work regardless of the underlying data store.


2 Answers

Perhaps you need

criteria.add(cb.like(emp.<String>get("name"), p)); 

because first argument of like() is Expression<String>, not Expression<?> as in equal().

Another approach is to enable generation of the static metamodel (see docs of your JPA implementation) and use typesafe Criteria API:

criteria.add(cb.like(emp.get(Employee_.name), p)); 

(Note that you can't get static metamodel from em.getMetamodel(), you need to generate it by external tools).

like image 146
axtavt Avatar answered Sep 23 '22 06:09

axtavt


Better: predicate (not ParameterExpression), like this :

List<Predicate> predicates = new ArrayList<Predicate>(); if(reference!=null){     Predicate condition = builder.like(root.<String>get("reference"),"%"+reference+"%");     predicates.add(condition); } 
like image 31
user3077341 Avatar answered Sep 26 '22 06:09

user3077341