Raf*_*nso 11 java hibernate jpa batch-insert
我需要使用EJB 3,Hibernate,Spring Data和Oracle进行大量插入.最初,我使用的是Spring Data,代码如下:
talaoAITDAO.save(taloes);
Run Code Online (Sandbox Code Playgroud)
其中talaoAITDAO是Spring Data JpaRepository子类,taloes是TalaoAIT实体的集合.在此实体中,其各自的ID具有以下形式:
@Id
@Column(name = "ID_TALAO_AIT")
@SequenceGenerator(name = "SQ_TALAO_AIT", sequenceName = "SQ_TALAO_AIT", allocationSize = 1000)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQ_TALAO_AIT")
private Long id;
Run Code Online (Sandbox Code Playgroud)
此实体也没有相关实体进行级联插入.
我的问题是,所有实体都是单独插入的(例如INSERT INTO TABLE(col1, col2) VALUES (val1, val2)).有时,它可能会导致超时,并且所有插入都将被回滚.我想要在批量插入中转换这些单独的插入(例如INSERT INTO TABLE(col1, col2) VALUES (val11, val12), (val21, val22), (val31, val32), ...).
研究替代方案以提高性能,我在hibernate文档中找到了这个页面,超出了 Hibernate批量大小混淆和其他页面.基于它们,我写了这段代码:
Session session = super.getEntityManager().unwrap(Session.class);
int batchSize = 1000;
for (int i = 0; i < taloes.size(); i++) {
TalaoAIT talaoAIT = taloes.get(i);
session.save(talaoAIT);
if(i % batchSize == 0) {
session.flush();
session.clear();
}
taloes.add(talaoAIT);
}
session.flush();
session.clear();
Run Code Online (Sandbox Code Playgroud)
另外,在peristence.xml中,我添加了以下属性:
<property name="hibernate.jdbc.batch_size" value="1000" />
<property name="order_inserts" value="true" />
Run Code Online (Sandbox Code Playgroud)
然而,虽然在我的测试中我发现了一个微妙的差异(主要是大集合和大批量),但它并没有那么大.在日志控制台中,我看到Hibernate继续进行单独插入,而不是替换它们进行大量插入.在我的实体中,我使用的是序列生成器,我相信它不是问题(根据Hibernate文档,如果我使用Identity生成器,我会遇到问题).
所以,我的问题是这里可能缺少什么.有些配置?有些方法未使用?
谢谢,
Rafael Afonso.
M. *_*num 15
有几件事.
首先,您的配置属性order_inserts必须是错误的hibernate.order_inserts.目前您的设置被忽略,您没有更改任何内容.
接下来使用EntityManager而不是做所有讨厌的hibernate东西.该EntityManager也有一个flush和clear方法.这至少应该清理你的方法.如果没有这个命令,这有助于清理会话并防止对那里的所有对象进行脏检查.
EntityManager em = getEntityManager();
int batchSize = 1000;
for (int i = 0; i < taloes.size(); i++) {
TalaoAIT talaoAIT = taloes.get(i);
em.persist(talaoAIT);
if(i % batchSize == 0) {
em.flush();
em.clear();
}
taloes.add(talaoAIT);
}
em.flush();
em.clear();
Run Code Online (Sandbox Code Playgroud)
接下来你不应该让你的批次变大,因为这可能会导致内存问题,从50开始,测试哪个/什么表现最好.有一点,脏检查将花费更多时间,然后刷新并清除到数据库.你想找到这个甜蜜点.
| 归档时间: |
|
| 查看次数: |
22332 次 |
| 最近记录: |