0

这个问题的根源是,什么会导致同步失败?这是一条通用消息,仅表示“出了点问题”,还是会话本身确实有问题? 有一些具有相似标题的线程,但似乎没有一个真正解决为什么 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())。

4

1 回答 1

2

不幸的是,我仍然不知道如何实际调试“无法将数据库状态与会话同步”,但我最终能够解决这个问题。

显然,数据库使用的 Oracle 表空间并未设置为增长,而是已填满。一旦表空间被设置为“可扩展”,这个错误就消失了。我非常怀疑这会帮助遇到同样问题的其他人,因为错误消息不适用,但是,你永远不知道。

于 2012-11-29T12:15:03.507 回答