处理JPA规范和spring-data-jpa时如何使用声明Stream作为返回类型

Waj*_*jax 5 spring jpql spring-data spring-data-jpa

我想知道是否可以在自定义查询中使用 JPA 规范谓词?

我试过了,但没有成功。

假设我有一个实体Customer和一个存储库:

@Repository
public interface CustomerRepository 
    extends JpaRepository<Customer, Long>,
   JpaSpecificationExecutor<Customer> {
}
Run Code Online (Sandbox Code Playgroud)

像这样查询是可以的

@Query("select c from Customer c")
Stream<Customer> streamAllCustomers();
Run Code Online (Sandbox Code Playgroud)

这不行

Stream<Customer> streamAllCustomersWithFilter(Specification<Customer> filter);
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这一目标?

NB我知道我可以把参数放在里面,@Query但我想留在当前应用程序的设计中并一直使用规范。

Eug*_*ene 7

我使用了一种从 Spring Data JPA 流式传输数据的方法。这种方法对于处理大量数据非常有用,同时避免高内存消耗,因为整个查询结果不会加载到内存中。

使用以下实现创建自定义个人存储库

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();
    }
Run Code Online (Sandbox Code Playgroud)

}

当然,这需要 JPA 2.2 支持 ORM 框架(我使用 Hibernate 5.3)。

另外,您应该注意在处理流时提供一个处于活动状态的连接。


Jen*_*der 2

TL;博士;

否,并且否,但是手动 是

我认为DATAJPA-906 问题回答了您的两个问题

  1. 问题(来自标题):在处理 JPA 规范和 spring-data-jpa 时如何使用声明 Stream 作为返回类型?

你不这样做,至少不以直接支持的方式:

JpaSpecificationExecutor 支持 Java 8 流

[..]

不幸的是,这必须等待 2.0 的改进,因为方法签名中的 Stream 会使接口在 Java < 8 的版本上不可加载。

当然,您始终可以添加自定义方法,包括实现

  1. 问题我可以在自定义查询中使用 JPA 规范谓词吗?(自定义查询是使用@Query注释定义的查询

您如何将通过规范定义的 CriteriaQuery 与手动定义的 JPQL 查询结合起来?

如果问题不清楚:如果您的自定义查询包含内部选择,那么规范中的条件应该放在哪里?

你可以做什么

实现一个自定义方法,返回一个 Stream 并以规范作为参数,将其与准备好的规范结合起来调用接口的现有方法JpaSpecificationExecutor并将结果转换为Stream