【发布时间】:2015-08-26 04:45:02
【问题描述】:
我有这种方法,它使用休眠将数千条记录插入数据库。
根据article,刷新和清除有助于释放一些宝贵的内存,下面的代码每 100 条记录执行一次。但问题是:
ORA-00001: 违反唯一约束 (OWNER.FOO_TABLE_PK)
总是在调用代码 session.flush() 时发生,也就是第 100 次保存之后(FOO_TABLE 的 PK 是一个简单的长 id)。我尝试完全删除 session.flush() 和 session.clear() 并在 session.save() 之后添加 session.evict(obj) 并解决了问题。我不确定这是否是一个好习惯。
你们知道为什么 session.flush() 会导致唯一约束错误吗?强烈建议定期冲洗和清理,但我不确定我是否正确使用它们。任何输入将不胜感激。谢谢!
@Override
@Transactional
public void bulkSave(List<Foo> objList) {
Session session = sessionFactory.getCurrentSession();
if (objList != null) {
if (!objList.isEmpty()) {
int counter = 0;
for (Foo obj : objList) {
session.save(objList);
counter++;
if ((counter % 100) == 0) {
session.flush();
session.clear();
}
}
}
}
}
【问题讨论】:
-
您的
Foo对象是如何创建的? -
@SubOptimal Foo 对象是在解析 excel 文件的过程之后创建的。它们都有 0 个 id,它们是数据库中的主键。
-
如果他们都有
0作为主键,那么你得到unique constraint异常是正常的。这个主键 id 在 Foo 类中是如何注解的? -
注释如下:@Id @SequenceGenerator(name = "idGenerator", sequenceName = "TABLE_ID_SEQ", allocationSize = 1) @GeneratedValue(generator = "idGenerator", strategy = GenerationType.SEQUENCE) @Column(name = "FOO_ID", nullable = false) 我相信 session.save() 会使用从 TABLE_ID_SEQ 生成的 ID 为对象提供一个新的 ID,所以 0 ids 对于新对象是正常的。跨度>
-
@SubOptimal,我很抱歉,因为我找到了唯一约束的原因。这不是 hibernate 的错,因为它只使用分配的序列生成器提供的 ID。有人使用绕过生成器的自定义 ID 手动将数据上传到数据库。当hibernate追上这个数字时,序列生成器提供的ID已经在数据库中使用了。