The method findAll(Sort) in the type JpaRepository

2019-08-20 10:50发布

问题:

I want to implement Specifications and want to use the findAll(Specification<T> spec) method, but always when I insert an Specification Eclipse tells me:

The method findAll(Sort) in the type JpaRepository<Telefonbuch,Long> is not applicable for the arguments (Specification<Telefonbuch>)

I don't want to use Sort. I hand over a specification so why does it always try to use the method with sort?

You can see here that the method is a suggestion by Eclipse: https://imgur.com/a/LuF6ZGK

Specification:

public interface Specification<T> {
    Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder);
}

TelefonbuchSpecifications:

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

TelefonbuchRepository:

public interface TelefonbuchRepository extends JpaRepository<Telefonbuch, Long>, JpaSpecificationExecutor<Telefonbuch> {

SearchController:

public void search(String vorname, String nachname, String telefonnummer, String handynummer) {  
    if (!vorname.isEmpty()) {   
        List<Telefonbuch> list = telefonbuchRepository.findAll(TelefonbuchSpecifications.hasVorname(vorname));
    }

And here at the

List<Telefonbuch> list = telefonbuchRepository.findAll(TelefonbuchSpecifications.hasVorname(vorname));
        }

it tells me: The method findAll(Sort) in the type JpaRepository<Telefonbuch,Long> is not applicable for the arguments (Specification<Telefonbuch>)

回答1:

findAll does exactly what it says: it finds all possibilities. So what you are trying to do is not making sense (filtering by first name).

findAll basically translates to SELECT * FROM TABLE

You will need to declare something in your repository which executes the query you are looking for, which I assume is SELECT * FROM TABLE WHERE <CONDITION>

As an example quoted from the spring docs portrays the following as a guideline:

The repository:

public interface PersonRepository extends Repository<User, Long> { 
    List<Person> findByLastname(String lastname);
}

Application:

public class SomeClient {

  @Autowired
  private PersonRepository repository;

  public void doSomething() {
    List<Person> persons = repository.findByLastname("Matthews");
  }
}

You will need to define a query which adheres to your needed condition, instead of attempting to force a condition on the findAll shortcut.



回答2:

Your repository additionally needs to implement JpaSpecificationExecutor to see the findAll(Specification<T>) method.

Also, note that we don't recommend to extend JpaRepository in the first place but rather use one of the less revealing interfaces CrudRepository or PagingAndSortingRepository. See this answer for reference.