【发布时间】:2012-10-18 14:44:07
【问题描述】:
这个问题的根源是,什么会导致同步失败?这是一条通用消息,仅表示“出了点问题”,还是会话本身确实有问题? 有一些标题相似的线程,但似乎没有一个能真正解决 hibernate 无法同步会话的原因,这只是人们忽略的错误消息的一部分。
我的具体案例/详细信息(尽管与上述问题确实相切):
在数据导入期间(20-120 分钟),我正在进行大量处理。直到整个域对象集被构建并验证一致性后,持久性才开始。在这段时间里,我构建了大约 200,000 个域对象。在该过程结束时,它会在它们之间循环,将它们全部保存到数据库中,并(出于性能原因)在每 50 或 100 个对象后刷新/清除会话。一旦持久化开始,域对象就不会改变。
这一切都发生在单个服务调用、单个事务中。我也无法在我的测试系统上重现它,它只发生在生产中。
我使用的是domainObj.save() 而不是session.saveOrUpdate(domainObj),我唯一一次手动触摸会话是在一组更新后刷新/清理它:
def session = sessionFactory.currentSession
session.flush()
session.clear()
这是抛出异常的地方。
紧跟在失败同步消息之后的是(可能是结果,但可能与原因有关):
Could not execute JDBC batch update; SQL [insert into domainB(field1, field2, etc) values (?, ?, ?)];
nested exception is org.hibernate.exception.ConstrainViolationException: Could not execute JDBC batch update
我意识到这个 ConstrainViolation(是的,“constrain”而不是“constraint”)似乎是一个数据错误,但数据集一直在工作,并且在没有更改导入文件或代码的情况下开始抛出此错误。它在其他系统上也继续工作,所以我已经在一定程度上排除了数据错误。
我几乎可以肯定,由于对象关系的性质,相同的对象会被多次保存。这是另一个提高性能的地方,但我认为这无关紧要,因为一旦保存了对象,就应该为其分配 ID,并且重新保存不会导致错误。
在这一点上我已经离题了,我不希望有人为我解决我的问题,但希望有人明确了解有关同步会话的内容,而不是“你确定你没有插入重复数据?”因为我尽可能确定(使用受约束的唯一字段作为键来查找要保存的域对象,遍历 Hashmap.keySet())。
【问题讨论】: