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.
Overview. JPA(Java Persistence API) specification lets you define which objects should be persisted, and how those objects should be persisted in your Java applications. JPA is considered the standard industry approach for Object to Relational Mapping (ORM) in the Java Industry.
Its findById method retrieves an entity by its id. The return value is Optional<T> . Optional<T> is a container object which may or may not contain a non-null value. If a value is present, isPresent returns true and get returns the value.
JPA's persist method returns void and Hibernate's save method returns the primary key of the entity.
Spring Data JPA is not an implementation or JPA provider, it's just an abstraction used to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.
There is the way to stream data from Spring Data JPA that I use. This approach is useful to process huge amount of data while avoiding high memory consumption, because whole query result is not loaded to memory.
Create custom individual repository with following implementation
public class YourCustomRepositoryImpl implements YourCustomRepository {
@PersistenceContext(unitName = "yorEntityManagerFactory")
private EntityManager em;
@Override
public Stream<SomeEntity> streamAll(Specification<SomeEntity> spec) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<SomeEntity> query = cb.createQuery(SomeEntity.class);
Root<SomeEntity> root = query.from(SomeEntity.class);
query.where(spec.toPredicate(root, query, cb));
return em.createQuery(query).getResultStream();
}
}
Sure, this requires JPA 2.2 supporting ORM framework (I used Hibernate 5.3).
Also, you should care to provide a connection to be alive while stream is being processed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With