Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use QueryDslJpaRepository?

In my current project setup I'm defining repositories as:

public interface CustomerRepository extends JpaRepository<Customer, Long>, QueryDslPredicateExecutor<Customer> {
}

The QueryDslPredicateExecutor provides additional findAll methods which return e.g. an Iterable. It e.g. does not contain a method to only specify an OrderSpecifier.

I just came across the QueryDslJpaRepository which contains more variants of these Predicate and OrderSpecifier aware methods, and also return Lists instead of Iterables.

I wonder why QueryDslPredicateExecutor is limited and if it is possible to use QueryDslJpaRepository methods?

like image 502
Marcel Overdijk Avatar asked Mar 17 '23 17:03

Marcel Overdijk


2 Answers

I used a custom BaseRepository already so It was easy to make sure my repositories use the List variant (instead of Iterable) using:

@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, QueryDslPredicateExecutor<T> {

    @Override
    List<T> findAll(Predicate predicate);

    @Override
    List<T> findAll(Predicate predicate, Sort sort);

    @Override
    List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);

    @Override
    List<T> findAll(OrderSpecifier<?>... orders);
}

Note that my commnent reagarding missing methods in QueryDslPredicateExecutor was incorrect.

like image 152
Marcel Overdijk Avatar answered Mar 19 '23 07:03

Marcel Overdijk


QueryDslJpaRepository extends SimpleJpaRepository

SimpleJpaRepository is used when you want to adding custom behavior to all repositories. It takes three steps to do so:

Step 1: Create an interface (eg CustomRepository) that extends JpaRepository, then add your own interface methods

Step 2: Create a class (eg CustomRepositoryImpl) that implements your CustomRepository, which naturally requires you to supply concrete method implementations to each and every method defined in not only CustomRepository but also JpaRepository as well as JpaRepository's ancestor interfaces. It'd be a tedious job, so Spring provide a SimpleJpaRepository concrete class to do that for you. So all you need to do is to make CustomRepositoryImpl to extend SimpleJpaRepository and then only write concrete method for the method in your own CustomRepository interface.

Step 3: make CustomRepositoryImpl the new base-class in the jpa configuration (either in xml or JavaConfig)

Similarly, QueryDslJpaRepository is the drop-in replacement for SimpleJpaRepository when your CustomRepository extends not only JpaRepository but also QueryDslPredicateExecutor interface, to add QueryDsl support to your repositories.

I wish Spring Data JPA document made it clear what to do if someone is using QueryDslPredicateExecutor but also wants to add his/her own customized methods. It took me some time to figure out what to do when the application throws errors like "No property findAll found for type xxx" or "No property exists found for type xxx".

like image 30
John Avatar answered Mar 19 '23 05:03

John