Search code examples
springspring-dataspring-data-jpajpql

How to use declare Stream as return type when dealing with JPA Specification and spring-data-jpa


I'm wondering if I can use JPA specification predicates in custom queries?

I've tried but with no success.

Let's say I have an Entity Customer and a repository:

@Repository
public interface CustomerRepository 
    extends JpaRepository<Customer, Long>,
   JpaSpecificationExecutor<Customer> {
}

Querying like this is OK

@Query("select c from Customer c")
Stream<Customer> streamAllCustomers();

This is Not OK

Stream<Customer> streamAllCustomersWithFilter(Specification<Customer> filter);

Is there a way to achieve this ?

NB I know I can put params in the @Query but I would like to stay in the design of the current app and use Specifications all the way.


Solution

  • TL;DR;

    No, and No, but manually Yes

    I think issue DATAJPA-906 answers both of your questions

    1. Question (from the title): How to use declare Stream as return type when dealing with JPA Specification and spring-data-jpa?

    You don't, at least not in a directly supported way:

    Support Java 8 Streams on JpaSpecificationExecutor

    [..]

    This unfortunately will have to wait for a 2.0 revamp as a Stream in the method signature would render the interface unloadable on versions of Java < 8.

    Of course you can always add your custom methods including implementation.

    1. Question Can I use JPA specification predicates in custom queries? (custom queries being queries defined using the @Query annotation

    how would you even combine a CriteriaQuery defined through a Specification and a manually defined JPQL query?

    In case the problem is not clear: If your custom query contains an inner select, wher should the Criteria from the specification go?

    What you can do

    Implement a custom method, returning a Stream and taking a specification as an argument, combine it with prepared specifications to call an existing method of the JpaSpecificationExecutor interface and convert the result to a Stream