【问题标题】:Hibernate SequenceGenerator returning incorrect nextvalHibernate SequenceGenerator 返回不正确的 nextval
【发布时间】:2012-04-25 20:52:50
【问题描述】:

这是我关于休眠的第二篇文章。自从我开始使用 hibernate 以来,它带来的问题比它解决的问题还多。这几乎让我觉得我应该坚持使用普通的旧 JDBC。总之,

这是我试图解决的问题之一。

.hbm 文件中的我的序列生成器如下所示。

<id name="id" type="long" column="ID">
    <generator class="sequence">
        <param name="sequence">ADVENTURES_ID_SEQ</param>
        <param name="allocationSize">1</param>
        <param name="initialValue">17599</param>
    </generator>
</id>

请注意:初始值为 17599。这是因为 oracle 序列中的 LAST_NUMBER 为:17599

CREATED         25-APR-12
LAST_DDL_TIME   25-APR-12
SEQUENCE_OWNER  ADVENTURE_ADMIN
SEQUENCE_NAME   ADVENTURES_ID_SEQ
MIN_VALUE       1
MAX_VALUE       9999999999999999999999999999
INCREMENT_BY    1
CYCLE_FLAG      N
ORDER_FLAG      N
CACHE_SIZE      20
LAST_NUMBER     17599

当我运行代码时,我看到在 Hibernate Debug 语句中生成的下一个序列为 200、201。

DEBUG SQL - select ADVENTURES_ID_SEQ.nextval from dual
DEBUG SequenceGenerator - Sequence identifier generated: 201

我预计 nextval 应该是 17600。似乎 oracle 序列根本没有被使用。

我的配置有什么问题以及如何修复它。非常感谢任何帮助。

谢谢

【问题讨论】:

  • 如果你在同一个数据库上运行select ADVENTURES_ID_SEQ.nextval from dual会产生什么?
  • 它给出了正确的值 17584、17585、17586 等。我们的 DBA 告诉我们信息表有时会显示不正确的值,在这种情况下是 17599。这个不正确的值是因为他们(Oracle)做了一些捷径来计算信息,它应该只用作指导。
  • 我也遇到过类似的问题,也许有些用户可能会感兴趣。从 Hibernate 3 升级到 Hibernate 5,发生了一些变化。在 Hibernate 3 中,我从未编写过“allocationSize”参数,并且一切正常。在 Hibernate 5 中,我必须指定 allocationSize=1。我使用的是注释,而不是 hbm 文件。

标签: oracle hibernate sequence-generators


【解决方案1】:

自我回答(解决方法):我仍然看到问题,但现在我有一个解决方法。因为它对我有用,所以我选择了完整的问题。

我让 Oracle 使用触发器生成 nextId:

create or replace
TRIGGER ADVENTURE_ADMIN.ADVENTURES_ID_TRIG 
BEFORE INSERT ON ADVENTURE_ADMIN.ADVENTURES FOR EACH ROW
WHEN (new.ID IS NULL)
BEGIN
    SELECT ADVENTURES_ID_SEQ.NEXTVAL INTO :new.ID FROM DUAL;  
END;

然后我让 hibernate 使用 Oracle 触发器生成的 ID。有两种方法可以做到这一点。

首先是使用 Hibernate select。这种方法的缺点是您将需要表中具有唯一约束的另一列,hibernate 将其用作获取行的键。这对我来说真的不起作用,因为我有以主键作为唯一唯一键的表。

第二是使用由 Jean-Pol Landrain、Martin Zeltner 创建的 TriggerAssignedIdentityGenerator。来源可以找到here。这使我能够解决为表找到另一个唯一键的问题。

以下是我的使用方法:

<id name="id" type="long" column="ID">
    <generator class="org.hibernate.id.TriggerAssignedIdentityGenerator" />
</id>

请注意:您使用的 Hibernate 版本很重要。我正在使用 3.5.4。休眠 3.6 对我不起作用。 JDBC 和 Oracle 驱动程序版本也很重要。您可以参考源文件中的文档。

【讨论】:

  • 很高兴我的 id 生成器帮助了你!您可以在 Hibernate 论坛上找到与此生成器相关的原始帖子。它现在已经相当老了,但是即使使用 Hibernate 4,许多人的贡献仍然使它保持活力。forum.hibernate.org/viewtopic.php?t=973262
  • @n00bc0der 你找到问题的原因了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 2020-10-30
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多