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

时间:2016-12-21 10:53:23

标签: spring spring-data spring-data-jpa jpql

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

我已经尝试但没有成功。

我们说我有一个实体Customer和一个存储库:

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

这样查询是好的

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

这不行

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

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

NB我知道我可以在@Query中添加参数但是我想留在当前应用程序的设计中并一直使用规范。

2 个答案:

答案 0 :(得分:1)

<强> TL; DR;

不,不,但手动是

我认为issue DATAJPA-906可以回答您的两个问题

  1. 问题(来自标题):如何在处理JPA规范和spring-data-jpa时使用声明Stream作为返回类型?
  2. 你没有,至少不是以直接支持的方式:

      

    在JpaSpecificationExecutor上支持Java 8 Streams

         

    [..]

         

    遗憾的是,由于方法签名中的Stream会在Java&lt;版本的Java上呈现无法加载的接口,因此必须等待2.0版本。 8。

    当然,您可以随时add your custom methods including implementation

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

      您如何组合通过规范定义的CriteriaQuery和手动定义的JPQL查询?

      如果问题不明确:如果您的自定义查询包含内部选择,那么规范中的条件应该如何?

      你能做什么

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

答案 1 :(得分:0)

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

通过以下实现创建custom individual repository

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();
    }

}

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

此外,您还应注意在处理流时提供连接以保持活动状态。