使用OneToMany层次结构的Spring Batch Bulk Insert

时间:2016-05-18 11:29:00

标签: hibernate jpa spring-batch transactional

我使用spring批处理来读取和转换树状实体,并使用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来持久保存所有&#34; B&#34;一次调用数据库的实体然后全部&#34; C&#34;实体等等...而不是每个实体的一个插入,因为我的调试日志正在显示。在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

简短的回答是,如果您正在使用Hibernate进行ORM实现,则应该

Hibernate Docs在某种程度上深入研究批处理here。如果配置正确,Hibernate将尝试在每个flush()期间(在每个块的末尾)按实体类型对插入和更新进行排序。

您还需要确保设置了以下属性,并且不使用IDENTITY生成器作为您的ID:

<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并且您的对象尚未在会话中(它不会),Hibernate将首先针对数据库发出select以确定是insert还是{{ 1}}是必需的。