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>

在我的名为“MYTEMP_TEMP_ID_SEQ”的 Oracle 数据库序列中,创建并在 Oracle 中正常工作。

现在,当我尝试使用休眠插入记录时,它给了我以下错误

org.hibernate.id.IdentifierGenerationException: 这个 id 生成器生成 long、integer、short 或 string

似乎当我的序列返回数字时,休眠将其视为 BigDecimal,而休眠的序列生成器类仅考虑长、整数、短和字符串的值。

Hibernate 不应该有 BigDecimal 的问题。但我认为他们还没有为序列生成器实现 BigDecimal

任何人都可以帮我解决问题吗?

谢谢。

4

3 回答 3

13

老实说,我无法想象为什么您会坚持将您的 ID 设为 BigDecimal 而不是 long。最大长值是9,223,372,036,854,775,807,尽管公认是最大 NUMBER(22) 值的大约千分之一,但确实应该足够了如果您要每秒生成一百万个标识符,那么您将不得不这样做300,000 年才能耗尽您的序列。

也就是说,为了让您的标识符生成为 BigDecimal,您需要编写自己的生成器。您可以通过扩展 Hibernate 的内置 SequenceGenerator 并覆盖其generate()方法来做到这一点。与其调用IdentifierGeneratorFactory.get()仅支持 long / int / short / String 的方法,不如从结果集中获取序列值作为 BigDecimal。

然后,您需要通过指定其完整类名来声明您的生成器:

<generator class="com.mypackage.BigDecimalGenerator">
  <param name="sequence">MYTEMP_TEMP_ID_SEQ</param>
</generator>
于 2009-08-15T00:25:08.373 回答
2

你设置正确的方言了吗?这应该足以让 Hibernate 理解序列的结果。

[编辑] 问题是您的序列类型与您的列的类型不匹配。序列(根据 Hibernate 的错误消息)可以转换为 long、integer、short 或 string,而您的序列返回 BigDecimal。

我建议将 ID 列的类型指定为“long”,即使 Oracle 不知道该类型。在内部,Hibernate 应该能够正确地为每个人转换所有内容。

于 2009-08-14T09:16:26.700 回答
2

确实。考虑到它可以生成的唯一记录的数量,长 id 必须足够。仅具有特殊值的特定生成器可能不是整数类型,或者出于某种原因可以控制整数类型值(可能是特定于项目的)。

此外,生成器是特定于数据库的,就像 oracle 的序列一样,所以方言定义也很重要。

于 2009-10-04T19:06:40.623 回答