hibernate - 具有 OneToMany 层次结构的 Spring Batch Bulk Insert

标签 hibernate jpa spring-batch transactional

我正在使用 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 来确定一个 insertupdate 是必需的。

关于hibernate - 具有 OneToMany 层次结构的 Spring Batch Bulk Insert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37298279/

相关文章:

java - 如何模拟调用同一类中存在的其他方法的方法

java - 尝试使用 spring 和 hibernate 用户 oracle db 时出错

java - hibernate :PSQLException:错误:列 "column_name"不存在

java - Hibernate 4.x MYSQL Multi-Tenancy ID 生成问题

java - JPA 条件查询 - 如何避免重复连接

java - 在关机时停止所有 Spring 批处理作业 (CTRL-C)

java - 如何避免 hibernate 中的字符串成员?

java - EclipseLink EntityManagerFactory 线程安全吗?

java - 在 @ManyToMany 映射中,未将数据插入数据库(空指针异常)

Java批量重启不处理步骤