gpt4 book ai didi

java - 使用 Spring Data JPA Stream 获取数据

转载 作者:行者123 更新时间:2023-12-01 21:16:20 35 4
gpt4 key购买 nike

下面是我的 Controller

public class TestController {

@PersistenceContext
EntityManager entityManager;

@Autowired
ProductAltRepository productAltRepository;

@GetMapping("/findAll")
@Transactional(readOnly = true)
public void findAll() {

Stream<ProductAltRelEntity> productAltRelEntities = productAltRepository.findAllProductAlts();
List<ProductAltRelEntity> productAlts = Lists.newArrayList();
productAltRelEntities.forEach(x -> {
productAlts.add(x);
entityManager.detach(x);
});
}

这是存储库

@Repository
@Transactional
public interface ProductAltRepository
extends JpaRepository<ProductAltRelEntity, Long>, JpaSpecificationExecutor<ProductAltRelEntity>{
@QueryHints(value = { @QueryHint(name = HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE),
@QueryHint(name = HINT_CACHEABLE, value = "false"), @QueryHint(name = HINT_READONLY, value = "true"), })
@Query("SELECT p FROM ProductAltRelEntity p")
public Stream<ProductAltRelEntity> findAllProductAlts();
}

需求是findAll(),分页导致OOM,所以想到使用Stream,但是出现异常。

    [WARN] org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 17068, SQLState: 99999

2019-11-15 12:30:31.468 ERROR 7484 --- [nio-8082-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Invalid argument(s) in call: setFetchSize [ERROR] org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Invalid argument(s) in call: setFetchSize 2019-11-15 12:30:31.793 ERROR 7484 --- [nio-8082-exec-1] c.s.e.d.d.e.GlobalExceptionHandler : Unhandled Exception: org.springframework.orm.jpa.JpaSystemException: could not execute query using scroll; nested exception is org.hibernate.exception.GenericJDBCException: could not execute query using scroll Caused by: org.hibernate.exception.GenericJDBCException: could not execute query using scroll Caused by: java.sql.SQLException: Invalid argument(s) in call: setFetchSize

最佳答案

读取错误日志,您需要将流代码放入 try block 中,即

try(Stream<ProductAltRelEntity> productAltRelEntities = productAltRepository.findAllProductAlts()){
List<ProductAltRelEntity> productAlts = Lists.newArrayList();
productAltRelEntities.forEach(x -> {
productAlts.add(x);
entityManager.detach(x);
});
} catch(Exception ex) {ex.printStackTrace();}

我注意到的另一件事是,您不需要将 @Transactional 放入 ProductAltRepository 中,因为您已经将其放入 TestController 中。

为了传输结果,我们需要满足三个条件:

Forward-only resultset
Read-only statement
Fetch-size set to Integer.MIN_VALUE

Forward-only 似乎已经由 Spring Data 设置,所以我们不必对此做任何特殊的事情。您的代码示例在 TestController 中已经有 @Transactional(readOnly = true) 注释,这足以满足第二个条件,因此 @QueryHint(name = HINT_READONLY, value = "true") 没有用。 fetch-size 似乎很有用。

以下是我的一个项目的摘录:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import static org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE;

public interface IssueRepo extends JpaRepository<Issue, Long>, JpaSpecificationExecutor<Issue> {

@QueryHints(value = @QueryHint(name = HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE))
@Query("select t from Issue t ")
Stream<Issue> getAll();
}

Controller

public class ManageIssue {
@GetMapping("all/issues")
@Transactional(readOnly = true)
public String getAll() {
System.out.println("Processing Streams ...");
try(Stream<Issue> issuesList = issueRepo.getAll()){

issuesList.forEach(issue -> {
System.out.println(issue.getId()+" Issue "+issue.getTitle());
});
} catch(Exception ex) {ex.printStackTrace();}
return "All";
}
}

关于java - 使用 Spring Data JPA Stream 获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58872030/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com