Hibernate SequenceGenerator返回错误的nextval

时间:2012-04-25 20:52:50

标签: oracle hibernate sequence-generators

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

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

由于

1 个答案:

答案 0 :(得分: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;

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

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

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

以下是我如何使用它:

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

请注意:您使用的Hibernate版本很重要。我正在使用3.5.4。 hibernate 3.6对我没用。 JDBC和Oracle Driver版本也很重要。您可以参考源文件中的文档来获取相同的文档。