2016-05-13 12 views
4

Ich habe eine Abfrage mit einem JOIN und ORDER BY und möchte es in meinem Repository mit dem Kriterium API verwenden.JpaSpecificationExecutor JOIN + ORDER BY in Spezifikation

Hier fand ich, wie Sie eine solche Abfrage in eine CriteriaQuery (Link) umbrechen.

CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); 
Root<Pet> pet = cq.from(Pet.class); 
Join<Pet, Owner> owner = cq.join(Pet_.owners); 
cq.select(pet); 
cq.orderBy(cb.asc(owner.get(Owner_.lastName),owner.get(Owner_.firstName))); 

Auf der anderen Seite, fand ich einige Beispiele, die die Kriterien Api in Kombination mit einem JpaRepository (example) zu verwenden.

Das Problem ist, dass alle Verfahren im Repository eine Spezifikation erwarten:

T findOne(Specification<T> spec); 

die immer wie folgt aufbauen:

public static Specification<PerfTest> statusSetEqual(final Status... statuses) { 
    return new Specification<PerfTest>() { 
     @Override 

     public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
      return cb.not(root.get("status").in((Object[]) statuses)); 
     } 
    }; 

} 

Also auf der einen Seite weiß ich, wie ein CriteriaQuery zu schaffen, und auf der anderen Seite brauche ich eine Spezifikation, die aus einem Prädikat aufgebaut ist, und ich kann nicht herausfinden, wie man die CriteriaQuery in eine Spezifikation/ein Prädikat zerlegt.

Antwort

6

Versuchen Sie so etwas wie dieses (ich nahm Haustier viele Besitzer hat):

public static Specification<Pet> ownerNameEqual(String ownerName) { 
     return new Specification<Pet>() { 
      @Override 
      public Predicate toPredicate(Root<Pet> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { 
       Join<Pet, Owner> owners = root.join("owners"); 
       criteriaQuery.orderBy(criteriaBuilder.desc(root.get("id"))); 
       return criteriaBuilder.equal(owners.get("name"), ownerName); 
      } 
     }; 
    } 

Dies ist nur ein Beispiel alle Tiere mindestens einen Eigentümer, dessen suchen hat den Namen gleich ownername

Aber Sie könnten stattdessen eine Methode List<Pet> findByOwnersNameOrderByIdDesc(String ownerName); in Ihrem Repository hinzufügen (als Äquivalent zur Spezifikation).

+0

wow, ich habe nicht erwartet, dass dies funktioniert, weil ich nicht erwartet habe, dass criteriaQuery später verwendet wird, aber es funktioniert – aschi