0

I followed this tutorial to get Spring Data JPA Specifications: https://dzone.com/articles/using-spring-data-jpa-specification

It worked to implement that for me, but I can't call the specifications methods to search for them. I want to have them in my SearchController:

This is the project Code: TelefonbuchSpecifications:

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

And now I want to call this method in my SearchController (SucheController), but I don't know how. At the moment the method looks like this: 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()]));
CptDayDreamer
  • 1,526
  • 6
  • 25
  • 61
  • You must use JPA repositories .Have a look at the CustomerRepository https://dzone.com/articles/using-spring-data-jpa-specification – Simon Martinelli Dec 27 '18 at 12:36
  • I use JPA repositories in my "TelefonbuchRepository": public interface TelefonbuchRepository extends JpaRepository – CptDayDreamer Dec 27 '18 at 12:38
  • but you commented out this line. What does not work? – Simon Martinelli Dec 27 '18 at 12:40
  • The method is undefined for SucheController. I can call it as TelefonbuchSpecifications.hasVorname(...) but not else. And even if i call it like this, I don't know how to use it like the predicates to have it like conditions – CptDayDreamer Dec 27 '18 at 12:46

1 Answers1

1

You need to have a a TelefonbuchRepository interface which implements JpaRepository and JpaSpecificationExecutor. The latter gives you methods, to which you can pass your 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)

Edit: 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()]));
   }
}
Robert Niestroj
  • 15,299
  • 14
  • 76
  • 119
  • Now i am calling telefonbuchRepository.findAll(TelefonbuchSpecifications.hasVorname(vorname)) but it won't give me anything – CptDayDreamer Jan 02 '19 at 14:36
  • Check the underlying SQL being generated. I'all also add to my answer how i generate my `Specification`. HTH. In your first code you use cb.equal which is wrong. In your second snippet you use builder exactly like me. – Robert Niestroj Jan 02 '19 at 15:04
  • Sorry but this can't be the right way. I don't know why this isn't working: https://dzone.com/articles/using-spring-data-jpa-specification I can't use the findAll method because it tells me: The method findAll(Sort) in the type JpaRepository is not applicable for the arguments (Specification) but why he thinks it is Sort when a Specification is given? He even shows me that there is .findAll (Specification spec) – CptDayDreamer Jan 09 '19 at 10:59
  • Can you take a look at this please? [Question](https://stackoverflow.com/questions/54950130/quiz-game-create-questions-answers-and-historical-for-admins) perhaps you can help me out. – Skizo-ozᴉʞS ツ Mar 10 '19 at 20:51