我正在使用序列在我的 Oracle 数据库中保存域对象实例。我在数据库中的每个表都有一个序列。例如,当我在用户或资源上使用保存功能时,它在第一次尝试时创建了一个新资源,但使用的 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

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

那是什么导致这个问题!

我看到表关联序列的下一个值字段中的下一个数字,在我来知道资源_sequence的下一个val= 42,因为资源表中的max(id)是41。

谢谢很多人的洞察力,以某种方式帮助我回顾真正的原因! 对于那些需要了解更多关于自定义方言的人, 它

其他提示

序列可以浪费数字,即表中的每个记录都不一定是下一个没有间隙之后的记录。换句话说,即使以前的DB记录具有ID= 41,你的事实也不会表明问题。

由于表中的最大ID为41

序列不会看到表的最大值并获取下一个。它们存储当前的序号,您将使用下一个值。

您可以查看实际数字:

select mysequence.currval from dual
.

您的问题是GRA.SYS_C0012183约束。查看此检查,如果这是您的主键,也许您可以使用一些更可读的名称,如my_table_pk ...

SYS_C0012183 主键约束?它的定义不仅仅是 id 列(我认为是由序列填充的列)?

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