3

这是我关于休眠的第二篇文章。自从我开始使用 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 序列根本没有被使用。

我的配置有什么问题以及如何修复它。任何帮助是极大的赞赏。

谢谢

4

1 回答 1

2

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

我让 Oracle 使用 Trigger 生成 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;

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

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

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

以下是我如何使用它:

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

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

于 2012-05-01T21:35:00.283 回答