Вызов спецификаций Spring Data JPA

Я следил за этим руководством, чтобы получить спецификации Spring Data JPA: https://dzone.com/articles/using-spring-data-jpa-specification

Для меня это сработало, но я не могу вызвать методы спецификаций для их поиска. Я хочу, чтобы они были в моем SearchController:

Вызов спецификаций Spring Data JPA Код: Технические характеристики:

public static Specification<Telefonbuch> hasVorname(String vorname) {
    return (root, query, cb) -> {
        return cb.equal(root.get(Telefonbuch_.vorname), "%"+vorname.toLowerCase()+"%");
    };
}

А теперь я хочу вызвать этот метод в моем SearchController (SucheController), но не знаю как. На данный момент метод выглядит так: SucheController:

   public void search(String vorname, String nachname, String telefonnummer, String handynummer) {  
    telefonbuch.setVorname(vorname);
    telefonbuch.setNachname(nachname);
    telefonbuch.setTelefonnummer(telefonnummer);
    telefonbuch.setHandynummer(handynummer);

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Telefonbuch> query = builder.createQuery(Telefonbuch.class);
    Root<Telefonbuch> root = query.from(Telefonbuch.class);
    List<Predicate> predicates = new ArrayList<Predicate>();



    if (!vorname.isEmpty()) {   
        //eintraege = telefonbuchRepository.findAll(hasVorname()); -> does not work
        Predicate condition = builder.like(builder.lower(root.get(Telefonbuch_.vorname)), "%"+vorname.toLowerCase()+"%");
        predicates.add(condition);
    }
...
query.select(root).where(predicates.toArray(new Predicate[predicates.size()]));

Вы должны использовать репозитории JPA. Взгляните на CustomerRepository dzone.com/articles/using-spring-data-jpa-specification

Simon Martinelli 27.12.2018 13:36

Я использую репозитории JPA в своем "TelefonbuchRepository": открытый интерфейс TelefonbuchRepository расширяет JpaRepository <Telefonbuch, Long>

CptDayDreamer 27.12.2018 13:38

но вы закомментировали эту строку. Что не работает?

Simon Martinelli 27.12.2018 13:40

Для SucheController метод не определен. Я могу назвать это TelefonbuchSpecifications.hasVorname (...), но не иначе. И даже если я назову это так, я не знаю, как использовать его как предикаты, чтобы он был как условия

CptDayDreamer 27.12.2018 13:46
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
1 426
1

Ответы 1

У вас должен быть интерфейс TelefonbuchRepository, который реализует JpaRepository и JpaSpecificationExecutor. Последний дает вам методы, которым вы можете передать свой Specification:

 - long     count(Specification<T> spec) 
 - List<T>  findAll(Specification<T> spec) 
 - Page<T>  findAll(Specification<T> spec, Pageable pageable)
 - List<T>  findAll(Specification<T> spec, Sort sort) 
 - Optional<T> findOne(Specification<T> spec)

Обновлено: MySpecification:

public class MyEntitySpecification implements Specification<MyEntity> {

   private final String searchText;

   public MyEntitySpecification(String searchText) {
      this.searchText = searchText;
   }

   @Override
   public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
      List<Predicate> predicates = new ArrayList<>();
      Optional.ofNullable(searchText).ifPresent(
         s -> predicates.add(cb.like(cb.lower(root.get(MyEntity_.searchString)), "%" + s.toLowerCase() + "%"))
      );
      return cb.and(predicates.toArray(new Predicate[predicates.size()]));
   }
}

Теперь я звоню на telefonbuchRepository.findAll (TelefonbuchSpecifications.hasV‌ orname (vorname)), но это мне ничего не даст

CptDayDreamer 02.01.2019 15:36

Проверьте генерируемый базовый SQL. Я также добавлю к своему ответу, как я генерирую свой Specification. HTH. В вашем первом коде вы используете cb.equal, что неверно. Во втором фрагменте вы используете конструктор, как и я.

Robert Niestroj 02.01.2019 16:04

Извините, но это не может быть правильным путем. Я не знаю, почему это не работает: dzone.com/articles/using-spring-data-jpa-specification Я не могу использовать метод findAll, потому что он сообщает мне: Метод findAll (Sort) в типе JpaRepository <Telefonbuch, Long> неприменим для аргументов (Спецификация < Telefonbuch>) но почему он думает, что это Сортировка, когда дается Спецификация? Он даже показывает мне, что существует .findAll (Specification <Telefonbuch> spec)

CptDayDreamer 09.01.2019 11:59

Вы можете взглянуть на это, пожалуйста? Вопрос, возможно, ты сможешь мне помочь.

Skizo-ozᴉʞS 10.03.2019 21:51

Другие вопросы по теме