我有实体项目和子输出(关系@OneToMany)。 在我的应用程序中,我需要通过数据库获取超过 50000 个项目,并在获取输出信息后。
获取50000个项目后,为了性能,我尝试使用parallelStream,但是当运行代码时,抛出异常:Illegal pop() with non-matching JdbcValuesSourceProcessingState
在我的搜索中,JdbcValuesSourceProcessingState 与休眠中的事务相关。
实体:
你能帮我吗?
public class Project {
@Id
private Long id;
private String name;
@OneToMany(mappedBy = "project")
private List<Output> outputs;
}
我的获取输出信息的代码:
List<Project> projects = projectRepository.findAll();
Set<SearchOutput> searchOutputs = Collections.synchronizedSet(new HashSet<>());
projects.parallelStream().forEach(project -> {
try {
project.getOutputs().forEach(output->{
SearchOutput searchOutput = new SearchOutput(project.getId(),output.getPath(),output.getName(),false);
searchOutputs.add(searchOutput);
});
} catch (Exception e) {
LOGGER.error("ProjectID: {} - {}", project.getId(), e.getMessage());
//throw new RuntimeException(e);
}
});
不要做这样的事情,尤其是在使用 JPA 时。您不想基本上从数据库中提取所有内容,扔掉 80% 并仅使用 3 个字段。由于多种原因,这是低效的。
相反,要么使用投影来返回您想要的结果,要么编写一个查询来准确返回您想要的结果。 JPQL 在这方面非常强大。
@Query("SELECT new SearchOutput(p.id, o.path, o.name, false) FROM Project p JOIN p.outputs o");
@QueryHints(@jakarta.persistence.QueryHint(name="org.hibernate.fetchSize", value="1000"))
Set<SearchOutput> findAllSearchOutput();
现在,如果有很多结果,您希望提高 jdbc 获取大小以减少网络往返。 (因此
@QueryHints
)。
有了这个,就不需要检索所有内容,但它会准确地检索你想要的内容。