2016-05-13 5 views
4

У меня есть запрос с использованием JOIN и ORDER BY и вы хотите использовать его в моем репозитории, используя Criteria Api.JpaSpecificationExecutor JOIN + ORDER BY in Спецификация

Здесь я нашел, как обернуть такой запрос в CriteriaQuery (Link).

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

С другой стороны, я нашел несколько примеров, чтобы использовать критерии Api в комбинации с JpaRepository (example).

Проблема в том, что все методы в хранилище ожидать Спецификация:

T findOne(Specification<T> spec); 

который всегда строить так:

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

} 

Таким образом, на одной стороне, я знаю, как создать CriteriaQuery, и с другой стороны мне нужна спецификация, которая строится из предиката, и я не могу понять, как разбирать CriteriaQuery в Спецификацию/Предикат.

ответ

6

Попробуйте что-то вроде этого (я предположил, животное имеет много владельцев):

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

Это просто пример для поиска всех домашних животных которых по крайней мере один владелец имеет имя, совпадающее OwnerName

Но вы можете добавить вместо этого метод List<Pet> findByOwnersNameOrderByIdDesc(String ownerName); (как эквивалент спецификации).

+0

wow, я не ожидал, что это сработает, потому что я не ожидал, что critQuery будет использоваться позже, но он работает – aschi

 Смежные вопросы

  • Нет связанных вопросов^_^