Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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 使用JPA EntityManager批插入_Java_Jakarta Ee_Ejb 3.0_Eclipselink - Fatal编程技术网

Java 使用JPA EntityManager批插入

Java 使用JPA EntityManager批插入,java,jakarta-ee,ejb-3.0,eclipselink,Java,Jakarta Ee,Ejb 3.0,Eclipselink,是否有一种方法可以使用JPA EntityManager使用批插入。我知道没有直接的方法来实现这一点,但必须有某种方法来实现这一机制 实际上,每次插入操作都需要300毫秒,我希望使用批插入而不是单个插入来减少这些操作 下面是我目前正在执行的单次插入代码 @PersistenceContext(unitName = "testing") EntityManager eM; Query querys = this.eM.createNativeQue

是否有一种方法可以使用JPA EntityManager使用批插入。我知道没有直接的方法来实现这一点,但必须有某种方法来实现这一机制

实际上,每次插入操作都需要300毫秒,我希望使用批插入而不是单个插入来减少这些操作

下面是我目前正在执行的单次插入代码

        @PersistenceContext(unitName = "testing")
        EntityManager eM;

        Query querys = this.eM.createNativeQuery(insertQuery);
        for (String s : someList) {
            //setting parameters
            querys.executeUpdate();
        }

提前感谢。

可以使用JPA执行批处理写入,但这在很大程度上取决于持久性提供程序、数据库和JDBC驱动程序的具体实现。例如,这说明了如何使用EclipseLink JPA 2.3和Oracle数据库启用批处理写入优化8。请在特定环境中查找类似的配置参数。

JPA本身没有任何批处理设置。但是,存在一些依赖于实现的设置

根据事务是否包含循环,批处理通常已经在您的案例中发生

JPA将在其一级缓存中收集您的所有更新,并且通常在事务提交时将这些更新成批写入DB。这与JDBC中的批处理并没有太大区别,在JDBC中,您添加的每个批处理项在调用update方法之前都暂时存在内存中

潜在的问题是,您根本无法保证JPA确实会执行此批处理,如果在事务提交或达到阈值时执行此操作,但我发现在几乎所有情况下,尤其是在涉及如此简单的更新循环的情况下,实际上JPA都会执行批处理

一个问题是,即使JPA确实已经进行了批处理,您仍然可能希望控制批大小。其他答案所链接的文章提供了非常有用的信息


最后,您应该知道一级缓存在循环中不断增长,因此如果更新的数量非常大,请定期清除它。或者,如果您的业务逻辑能够支持它,则在多个事务中执行部分更新。例如,事务处理1中的项目0至100.000,事务处理2中的项目100.001至200.000等。

我知道这是一个相当古老的问题,有一个公认的答案。尽管如此,我还是想给这个非常具体的主题一个新的答案

@PersistenceContext
private EntityManager entityManager;

@Value("${hibernate.jdbc.batch_size}")
private int batchSize;

public <T extends MyClass> Collection<T> bulkSave(Collection<T> entities) {
  final List<T> savedEntities = new ArrayList<T>(entities.size());
  int i = 0;
  for (T t : entities) {
    savedEntities.add(persistOrMerge(t));
    i++;
    if (i % batchSize == 0) {
      // Flush a batch of inserts and release memory.
      entityManager.flush();
      entityManager.clear();
    }
  }
  return savedEntities;
}

private <T extends MyClass> T persistOrMerge(T t) {
  if (t.getId() == null) {
    entityManager.persist(t);
    return t;
  } else {
    return entityManager.merge(t);
  }
}

来源:

Hi,你能给我一些代码片段吗?如何在上面提供的代码中使用相同的代码。@Rana正如我上面所说的:这取决于你使用的持久性提供程序-我看不出代码,你必须告诉我。Hi,我使用的是org.eclipse.persistence.jpa.PersistenceProvider。另外,如果使用批插入有任何限制,请告诉我。@Rana这都在链接文章中,您必须编辑persistence.xml文件并添加类似的内容。请先花点时间阅读这篇文章。嗨,我已经补充了这一点,我正在寻找我需要使用这一声明来观察的任何陷阱的信息。谢谢。嘿,我现在用的是spring数据jpa,所以你的意思是,如果我在一个方法内的一个循环中更新对象,并且这个方法用@Transactional标记,它会像jdbc批量更新一样自动批量更新。我想我们需要再次刷新并在最后清除,以保存任何未完成批量大小的剩余对象?参见我的示例