Oracle Hibernate序列生成器问题

3

我正在使用Oracle 11g、Java(struts2)和Hibernate开发一个应用程序。

我有一个名为mytemp的表,其中列mytemp_id的类型为NUMBER(22,0)。

在我的mytemp.hbm.xml文件中,id如下所示:

<id name="mytempId" type="big_decimal">
        <column name="MYTEMP_ID" precision="22" scale="0" />
        <generator class="sequence">
            <param name="sequence">MYTEMP_TEMP_ID_SEQ</param>
        </generator>
    </id>

在我的Oracle数据库中,有一个名为“MYTEMP_TEMP_ID_SEQ”的序列,它在Oracle中创建并正常工作。
现在,当我尝试使用Hibernate插入记录时,它会给我以下错误信息:
org.hibernate.id.IdentifierGenerationException: this id generator generates long, integer, short or string
看起来,由于我的序列返回Number类型,而Hibernate的序列生成器类只考虑long、integer、short和string类型的值,因此Hibernate将其视为BigDecimal类型。
Hibernate不应该对BigDecimal类型有问题。但是我认为他们没有为序列生成器实现BigDecimal。
有人能帮助我解决这个问题吗?
谢谢。
3个回答

13
老实说,我无法想象为什么你坚持要将ID作为BigDecimal而不是long类型。最大的long值是9,223,372,036,854,775,807,尽管它确实只是最大NUMBER(22)值的约千分之一,但应该已经足够了。如果你每秒生成一百万个标识符,那么你需要这样做300,000年才能用完你的序列。
话虽如此,为了将你的标识符生成为BigDecimal,你需要编写自己的生成器。你可以通过扩展Hibernate内置的SequenceGenerator并覆盖其generate()方法来实现这一点。你需要从结果集中获取BigDecimal类型的序列值,而不是调用IdentifierGeneratorFactory.get(),因为它仅支持long/int/short/String类型。
然后,你需要声明你的生成器,指定其完整类名。
<generator class="com.mypackage.BigDecimalGenerator">
  <param name="sequence">MYTEMP_TEMP_ID_SEQ</param>
</generator>

1
你好ChssPly76,感谢您的回复。我将我的Hibernate转换为在Hibernate中使用长整型,无论何时都使用BigDecimal来使用序列。这解决了我的问题。我在这里发布它是为了知道如何扩展Hibernate IdentifierGenerator类以使用BigDecimal进行序列生成器。我不是很明白。但是将BigDecimal转换为long肯定可以解决问题。谢谢。 - amar4kintu
我在上面的回答中解释了如何扩展SequenceGenerator。看一下它的generate()方法 - 你基本上会复制整个方法,并将IdentifierGeneratorFactory.get()替换为resultSet.get()以获取你的BigDecimal值。 - ChssPly76
我在我的Hibernate生成文件中将所有的big_decimal字段设置为long类型,现在它可以正常工作了。谢谢你的支持。 - amar4kintu

2

当然。长的ID必须足够考虑到它可以生成的唯一记录数量。特定的生成器仅需要具有特殊值,可能不是整数类型,或者由于某些原因(可能是项目特定),需要对整数类型值进行控制。

此外,生成器是数据库特定的,例如oracle的序列,因此方言定义也很重要。


2
你是否设置了正确的方言?这应该足以让Hibernate理解序列的结果。
[编辑]问题在于你的序列类型与列的类型不匹配。序列(根据Hibernate的错误信息)可以转换为long、integer、short或string,而你的序列返回一个BigDecimal。
我建议将ID列的类型指定为"long",即使Oracle不知道那种类型。在内部,Hibernate应该能够正确地为每个人进行转换。

是的..以下是我的方言<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> - amar4kintu
在这种情况下,您的ID列的类型是问题所在。请查看我的编辑。 - Aaron Digulla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接