我使用序列在我的oracle数据库中保存域对象实例。 我有一个数据库中每个表的序列。 例如,当我在User或Resource上使用保存功能时,它首次尝试创建了一个新资源,但使用的ID是70?序列显示正确的下一个数字 - 42因为表中的最大ID是41.为什么id = 70用于插入新资源?
同样从下一次尝试所有插入失败并出现此错误
org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into GRARESOURCE (decomm
issioned, disabled, criticality, resourceClass, resourceGroupId, resourceName, ownerId, resourceSegmentId, resourceTypeId, riskSco
re, targetIP, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; constraint [GRA.SYS_C0012183]; nested exception is org.hibernate.e
xception.ConstraintViolationException: Could not execute JDBC batch update
不确定是什么问题,因为这是在代码重组后发生的......我们将代码移到了新的包中..
编辑:我找到了原因,看到了我的回答。谢谢你们。答案 0 :(得分:1)
序列可能会浪费数字,即表格中的每个记录不一定都是一个没有间隙的记录。换句话说,即使前一个DB记录的ID = 41,你的数据也会跳到70,这并不表示存在问题。
答案 1 :(得分:1)
因为表中的最大ID是41
序列没有看到表的最大值并获得下一个表。它们存储当前的序列号,您将使用下一个值。
您可以使用以下方法检查实际号码:
select mysequence.currval from dual
您的问题是GRA.SYS_C0012183
约束。看看这是什么,如果这是你的主键,也许你可以使用一些更易读的名字,比如MY_TABLE_PK ......
答案 2 :(得分:0)
SYS_C0012183
是主键约束吗?是不是只定义了id
列(我假设,序列填充的列)?
答案 3 :(得分:0)
我意识到问题的主要原因。 我之前使用过SequencePerTableOracleDialect,我是从Burt Beckwith之前的帖子中得到的。当应用程序启动时,方言为每个表创建一个新序列,类似于转换为表的域类。 方言还确保每个表的id序列仅通过其序列进行管理,并且公共序列不用于数据库中的所有插入(这是默认策略) 在代码重组期间,我删除了自定义方言,并使用默认的10g方言。
这是导致问题的原因!
我看到表中的下一个数字与序列的下一个值字段相关联,我知道下一个val = 42表示资源表,其中资源表中的max(id)为41,这是正确的。
非常感谢有识之士在某种程度上帮助我回忆真正的事业! 对于那些需要了解更多关于定制方言的人, 它的Here