java - 插入大量行而不将实体附加到持久性上下文

标签 java spring spring-boot spring-data spring-data-jpa

在通过“数据提供者”进行流式传输时,我需要在数据库中插入相当大量的实体,比如大约 100,000 个。整个步骤需要是事务性的。
为了尽可能简化我的用例,我们假设这是我的代码:

@Transactional
public void execute() {
    for (int i = 0; i < 100000; i++) {
        carRespository.save(new Car());
    }
}

此代码的问题在于,即使很明显,在生成插入查询后我对 Car 实体没有用处,该实体附加到持久性上下文并保存在内存中,直到事务处理完成。
我想确保在触发垃圾收集的情况下,创建的实体被清除。目前我看到两种解决方案:

  • 在存储库上创建 native 插入查询
  • 在服务中注入(inject) EntityManager 并在每次插入后调用 em.detach(car)

我倾向于选择第二个选项,因为我不必在实体更改时管理 native 插入语句。

您能否确认我采取了正确的方法或提出更好的替代方案?

最佳答案

您可以在 Hibernate documentation 中找到批量插入数据的方式。

When making new objects persistent flush() and then clear() the session regularly in order to control the size of the first-level cache.

因此建议采用以下方法:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    session.save(new Car());
    if (i%20 == 0 ) {
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close(); 

关于java - 插入大量行而不将实体附加到持久性上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39680212/

相关文章:

java - 在JAVA中显示JTable中所有反序列化的对象

java - 如何使用 <join> 标记加入 hibernate 映射文件中的两列?

java - 没有 Spring 的 Atomikos 事务管理器

html - Thymeleaf:循环后删除包含迭代属性(th:each)或评估后包含条件属性(th:if)的div

java - 使用 Spring Security 手动实现登录

java - WUT-121 该文件传输已被管理员禁止

java - JTextField - 使用按钮移动光标

java - @Autowire 调用期间未实例化服务类

java - 我的配置 spring sessionFactory 配置有什么问题?

spring-boot - 找不到org.elasticsearch.client.Cancellable的类文件