我正在使用 spring batch 读取和转换树状实体并使用 JpaItemWriter 写入 oracle 数据库。对于树状实体,我的意思是:
class A {
@OneToMany
List<B> bList;
}
class B {
@OneToMany
List<C> cList;
}
class C {
@OneToMany
List<D> dList;
}
class D {
}
关系的大小可以快速增长,但出于业务原因,需要在一次事务中同时保留整个实体。有了这个 4 级层次结构,我想知道是否可以使用一些 Hibernate(JPA 首选)方法在自上而下的策略中调用批量插入,使用 spring JpaItemWriter 通过一次调用数据库来持久化所有“B”实体然后是所有“C”实体等等......而不是像我的调试日志显示的那样为每个实体插入一个。在此先感谢您的帮助。
最佳答案
简短的回答是,如果您将 Hibernate 用于您的 ORM 实现,它应该是可能的。
Hibernate 文档在某种程度上深入研究了批处理 here .如果配置正确,Hibernate 将尝试在每个 flush()
期间(在每个 block 的末尾)按实体类型对您的插入和更新进行排序。
您还需要确保设置了以下属性并且您没有为您的 ID 使用 IDENTITY 生成器:
<prop key="hibernate.jdbc.batch_size">50<!--or some other number--></prop>
<prop key="hibernate.order_inserts">true</prop>
<prop key="hibernate.order_updates">true</prop>
<prop key="hibernate.jdbc.batch_versioned_data">true</prop>
这Red Hat example如何用持久性单元做同样的事情。
现在,综上所述,Hibernate 可能很敏感,因此您可能想要增加 BatchingBatcher 类的日志记录以确认它实际上正在对您的插入进行批处理。最后,注意任何不使用序列的实体中的 saveOrUpdate()
方法。如果你正在定义你自己的 ID 而你的对象还没有在 session 中(它不会),Hibernate 将首先对数据库发出一个 select
来确定一个 insert
或 update
是必需的。
关于hibernate - 具有 OneToMany 层次结构的 Spring Batch Bulk Insert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37298279/