oracle序列搞砸了,插入失败了吗?

时间:2012-03-14 01:14:37

标签: oracle sequences ora-00001

我使用序列在我的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

不确定是什么问题,因为这是在代码重组后发生的......我们将代码移到了新的包中..

编辑:我找到了原因,看到了我的回答。谢谢你们。

4 个答案:

答案 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列(我假设,序列填充的列)?

  • 如何确定序列的下一个值是42?您是否正在为此运行单独的查询?
  • 您是否期望序列能够为您提供无差距数字?如果是这样,那就是您的期望问题。序列返回不同的值但它们不保证不存在间隙(实际上,可以保证存在间隙,因为数据库关闭或序列从共享池中清除或事务已回滚)。
  • 你如何使用序列?桌子上有触发器吗?或者Hibernate配置为使用序列?如果Hibernate配置为使用序列,请发布该配置。

答案 3 :(得分:0)

我意识到问题的主要原因。 我之前使用过SequencePerTableOracleDialect,我是从Burt Beckwith之前的帖子中得到的。当应用程序启动时,方言为每个表创建一个新序列,类似于转换为表的域类。 方言还确保每个表的id序列仅通过其序列进行管理,并且公共序列不用于数据库中的所有插入(这是默认策略) 在代码重组期间,我删除了自定义方言,并使用默认的10g方言。

这是导致问题的原因!

我看到表中的下一个数字与序列的下一个值字段相关联,我知道下一个val = 42表示资源表,其中资源表中的max(id)为41,这是正确的。

非常感谢有识之士在某种程度上帮助我回忆真正的事业! 对于那些需要了解更多关于定制方言的人, 它的Here