2010-10-25 13 views
40

Ich versuche Criteria API in meinem neuen Projekt zu verwenden:JPA/Criteria API - wie & gleiches Problem

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

, wenn ich diese Zeile:

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

zu:

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

ich erhalte eine Fehlermeldung, dass:

Verfahren wie (Expression, Expression) in der Art CriteriaBuilder ist nicht> anwendbar für die Argumente (Path, Parameterexpression)

Was ist das Problem?

Antwort

66

Vielleicht brauchen Sie

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

weil erstes Argument von like()Expression<String> ist, nicht Expression<?> wie in equal().

Ein weiterer Ansatz ist die Erzeugung des statischen Metamodell zu ermöglichen (docs Ihrer JPA-Implementierung sehen) und typsichere Criteria API verwenden:

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

(Beachten Sie, dass Sie nicht statisch Metamodell von em.getMetamodel() bekommen können, müssen Sie um es mit externen Tools zu generieren).

+0

"name" hier ist der Variablenname des Parameters hier? wie: name in jpql? –

+0

@axtavt, wie ich den Fall ignorieren kann –

12

Besser: Prädikat (nicht ParameterExpression), wie folgt aus:

List<Predicate> predicates = new ArrayList<Predicate>(); 
if(reference!=null){ 
    Predicate condition = builder.like(root.<String>get("reference"),"%"+reference+"%"); 
    predicates.add(condition); 
}