便携式JPA批量/批量插入 [英] Portable JPA Batch / Bulk Insert

查看:189
本文介绍了便携式JPA批量/批量插入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是跳了一个别人写的功能,效率似乎有些低下,但是我对JPA的了解不足以找到一种非Hibernate专用的便携式解决方案.

简而言之,在循环中调用以插入每个新实体的Dao方法将执行"entityManager.merge(object);".

JPA规范中是否定义了一种方法,可以将实体列表传递给Dao方法,并进行批量/批处理插入,而不是为每个单个对象调用merge?

另外,由于Dao方法带有"@Transactional"注释,我想知道是否每个合并调用都在其自己的事务中进行...这对性能没有帮助.

有什么主意吗?

解决方案

在原始JPA中没有批量插入操作.

是的,每个插入操作都将在其自己的事务中完成. @Transactional属性(没有限定符)表示传播级别为REQUIRED(如果尚不存在,则创建一个事务).假设您有:

public class Dao {
  @Transactional
  public void insert(SomeEntity entity) {
    ...
  }
}

您这样做:

public class Batch {
  private Dao dao;

  @Transactional
  public void insert(List<SomeEntity> entities) {
    for (SomeEntity entity : entities) {
      dao.insert(entity);
    }
  }

  public void setDao(Dao dao) {
    this.dao = dao;
  }
}

这样,整个插入组就被包装在一个事务中.如果您正在谈论大量插入,您可能希望将其分为1000、10000或其他类,因为足够大的未提交事务可能会使资源数据库饿死,并且可能仅由于大小而导致失败.

注意:@Transactional是Spring注释.请参阅Spring Reference中的事务管理.

I just jumped on a feature written by someone else that seems slightly inefficient, but my knowledge of JPA isn't that good to find a portable solution that's not Hibernate specific.

In a nutshell the Dao method called within a loop to insert each one of the new entities does a "entityManager.merge(object);".

Isnt' there a way defined in the JPA specs to pass a list of entities to the Dao method and do a bulk / batch insert instead of calling merge for every single object?

Plus since the Dao method is annotated w/ "@Transactional" I'm wondering if every single merge call is happening within its own transaction... which would not help performance.

Any idea?

解决方案

No there is no batch insert operation in vanilla JPA.

Yes, each insert will be done within its own transaction. The @Transactional attribute (with no qualifiers) means a propagation level of REQUIRED (create a transaction if it doesn't exist already). Assuming you have:

public class Dao {
  @Transactional
  public void insert(SomeEntity entity) {
    ...
  }
}

you do this:

public class Batch {
  private Dao dao;

  @Transactional
  public void insert(List<SomeEntity> entities) {
    for (SomeEntity entity : entities) {
      dao.insert(entity);
    }
  }

  public void setDao(Dao dao) {
    this.dao = dao;
  }
}

That way the entire group of inserts gets wrapped in a single transaction. If you're talking about a very large number of inserts you may want to split it into groups of 1000, 10000 or whatever works as a sufficiently large uncommitted transaction may starve the database of resources and possibly fail due to size alone.

Note: @Transactional is a Spring annotation. See Transactional Management from the Spring Reference.

这篇关于便携式JPA批量/批量插入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆