【发布时间】:2019-11-03 01:08:52
【问题描述】:
这是场景,我正在使用 Spring Data JPA JpaRepository 保存一个实体(我们称之为 CG 实体)。在这个 CG 实体中,我们有很多实体 One-One、One-Many 和 M-M,在这些实体内部,还有更多的关系等等。我通过其主键设置 CG 实体并向其添加其他实体对象。所以基本上这个 CG 实体 PK 应该用作 CG 中大多数其他实体的 FK。
一些实体是新的,而另一些实体是通过创建具有给定主 ID 的对象来设置的(因此无需使用相关的存储库来查找和设置对象)。在模型类中,所有的初选都是手动设置的(没有自动生成策略)(我不能公开表结构,因为我不允许这样做) 当我调用 .save() 函数时,JPA 运行此函数
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
从这里 Spring JPA 通过创建选择查询来检查 CG 是否是新实体。当我使用调试器中显示的 SQL 查询时,我观察到它使用了近 70 个 SELECT 查询。
在 spring 文档Persistable 中,我实现了它并将覆盖isNew() 设置为false。我对那些由 PK 创建的对象做了同样的事情。
但是当我为整个操作调用.save()时,spring data JPA在插入前运行了近800个SELECT查询,并且有70个INSERT查询(插入查询没有问题)。保存条目大约需要 20 秒。我提到了很多与此场景相关的线程,但无法找到一个好的 SPRING DATA JPA 解决方案。 (所以Thread 1)
我所需要的只是减少保存 CG 实体的时间。有没有 Spring Data JPA 方法来实现这一点?
【问题讨论】:
-
这不是 Spring Data JPA,而只是 JPA“问题”。这就是 JPA 的工作方式,与调用保存/合并无关。对于现有实体,它将进行脏检查以查看是否需要更新内容,它还将尝试在这些实体(选择)中加载引用。您想要的是优化批处理的此过程并将刷新模式设置为手动(而不是自动)并定期刷新和清除(按此顺序)第一级缓存(实体管理器)。
-
@M.Deinum 所以你的意思是我必须手动实现保存查询?你能分享一些关于你所说的教程吗?谢谢回复
-
不,我不是。我是说您应该针对批处理进行优化,从而将刷新模式设置为手动并定期调用
flush和clear。我没有说你应该编写自己的查询。 -
@M.Deinum 啊谢谢你的推荐,我去看看批处理。
-
您需要使用构建和保存实体的代码更新您的问题。
标签: java spring hibernate jpa spring-data-jpa