Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 插入大量行,而不将实体附加到持久性上下文_Java_Spring_Spring Boot_Spring Data_Spring Data Jpa - Fatal编程技术网

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

Java 插入大量行,而不将实体附加到持久性上下文,java,spring,spring-boot,spring-data,spring-data-jpa,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()); } } @Transactional public void execut

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

@Transactional
public void execute() {
    for (int i = 0; i < 100000; i++) {
        carRespository.save(new Car());
    }
}
@Transactional
public void execute(){
对于(int i=0;i<100000;i++){
carRespository.save(新车());
}
}
此代码的问题在于,即使在生成insert查询后很明显我没有使用Car实体,实体也会附加到持久性上下文,并保存在内存中,直到事务完成。
我希望确保在触发垃圾收集的情况下,已创建的实体被清除。为此,我目前看到两种解决方案:

  • 在存储库上创建本机插入查询
  • 在服务中插入
    EntityManager
    ,并在每次插入后调用
    em.detach(car)
我倾向于选择第二个选项,因为我不必在实体更改时管理本机insert语句

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

您可以找到插入该批数据的方法

使新对象持久化时,请定期刷新()然后清除()会话,以控制一级缓存的大小

因此,建议采用以下方法:

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(); 
Session Session=sessionFactory.openSession();
事务tx=会话.beginTransaction();

对于(inti=0;i您可以尝试使用spring数据JPA中的方法,而不是
save()

据我所知,这将在现场将插入刷新到db。我对这一部分没有问题:从我的观点来看,这可以是单个插入或批插入。我感兴趣的是,确保实体可用于gc的最佳方法是什么。这将是“纯插入”Hibernate是实现我的第二个建议(使用detach的建议)的一种方式。我承认您的建议是“偶尔”清除实体。我也可以使用
em.clear()
来实现这一点。