由于列(Oracle)的值太大,违反了唯一约束

时间:2019-06-14 15:32:57

标签: sql database oracle hibernate

能否获得

  

ORA-00001:违反了唯一约束(XXX)

由于

  

ORA-12899:列(XXX)的值太大

在使用Hibernate的oracle数据库中(如this confluence page中所述)?

(每个错误的列在不同的表中,但彼此相关)

在这种情况下,这怎么可能?

*更新*

我可以确认异常之间的因果关系。给定的情况如下:

是对数据库执行不同操作的许多进程。直到Hibernate会话刷新为止,将一直堆叠此操作。当您调用flush方法时,查询是在同一事务中执行的。

在我的特定情况下,我拥有在实体C内部都有的实体A和B(该实体的引用相同,每个父实体没有副本)。当程序尝试保存A(字符串字段太大)时,首先执行C插入查询,然后执行对实体本身的插入,从而导致“ ORA-12899:列的值太大”。此时,C在数据库中,但尚未提交。 然后,下一个过程尝试保存包含C实体的B,这会导致C实体上出现“ ORA-00001:违反唯一约束”。

我的问题是:

  • 当第一个进程没有错误(没有太大的列)时,第二个进程不再尝试再次插入C,而仅将插入插入实体B(可能是实体C的分离状态)。
  • 为什么没有在第一个错误时中止执行?

1 个答案:

答案 0 :(得分:0)

两个异常(唯一约束和列的值太大)都相关。在单个事务中执行服务器进程。这些进程将调用方法save()或saveOrUpdate()堆栈查询,直到Hibernate会话的flush()或提交事务为止。

在给定场景下,有时会调用会话的flush():

实体A和B都包含与实体C相同的引用。第一个过程尝试插入实体A,因此首先无问题地执行C的插入,随后尝试插入A,但由于列异常太大而失败。此时,C处于数据库中(尚未提交),但是由于先前的失败,休眠会话处于不连贯的状态,并且Hibernate不知道插入了C(会话刷新失败不会触发回滚,这是服务器的责任。开发人员)。

然后执行第二个过程,并尝试将B插入数据库。如果前面的过程正常,则Hibernate仅插入实体B,因为他知道数据库中已经存在C。由于会话状态不一致,因此Hibernate尝试再次将C实体保存在数据库中,从而引发唯一约束异常。