2010-10-25 21 views
40

J'essaie d'utiliser l'API de critères dans mon nouveau projet:API JPA/Critères - Comme et même problème

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

Maintenant, quand je change cette ligne:

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

à:

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

Je reçois une erreur disant:

La méthode comme (Expression, Expression) dans le type CriteriaBuilder n'est pas> applicable aux arguments (chemin, ParameterExpression)

Quel est le problème?

Répondre

66

Peut-être vous avez besoin

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

parce que le premier argument de like() est Expression<String>, pas Expression<?> comme dans equal().

Une autre approche est de permettre la génération du métamodèle statique (voir docs de votre implémentation JPA) et utiliser typesafe API Critères:

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

(Notez que vous ne pouvez pas obtenir métamodèle statique de em.getMetamodel(), vous avez besoin pour le générer par des outils externes).

+0

"nom" ici est le nom de la variable du paramètre ici? comme: nom en jpql? –

+0

@axtavt, comment je peux ignorer le cas –

12

Mieux: prédicat (non ParameterExpression), comme ceci:

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