【问题标题】:Oracle hibernate sequence generator problemoracle休眠序列生成器问题
【发布时间】:2009-08-14 09:09:52
【问题描述】:

我正在使用 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 中正常工作。

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

org.hibernate.id.IdentifierGenerationException:此 id 生成器生成长、整数、短或字符串

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

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

谁能帮我解决这个问题?

谢谢。

【问题讨论】:

    标签: oracle hibernate numbers bigdecimal


    【解决方案1】:

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

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

    然后您需要通过指定其完整的类名来declare your generator

    <generator class="com.mypackage.BigDecimalGenerator">
      <param name="sequence">MYTEMP_TEMP_ID_SEQ</param>
    </generator>
    

    【讨论】:

    • 您好 ChssPly76,感谢您的回复。我将我的休眠转换为使用 long ,只要有 BigDecimal 在休眠中使用序列。它解决了我的问题。我在这里发布它以了解如何扩展休眠标识符生成器类以将 bigDecimal 用于序列生成器。我不完全明白。但是将 BigDecimal 转换为 long 可以肯定地解决问题。谢谢。
    • 我已经在上面的回答中解释了如何扩展SequenceGenerator。看看它的generate() 方法 - 你基本上会复制整个东西并将IdentifierGeneratorFactory.get() 替换为resultSet.get() 以获得你的BigDecimal 值。
    • 我将所有 big_decimal 字段设置为在我的休眠生成文件中被认为是长的。所以它现在可以正常工作了。谢谢..您的支持..
    【解决方案2】:

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

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

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

    【讨论】:

    • 是的.. 以下是我的方言org.hibernate.dialect.Oracle10gDialect
    • 在这种情况下,您的 ID 列的类型是问题所在。查看我的编辑。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 2012-09-09
      • 2010-11-14
      • 2015-05-18
      • 1970-01-01
      相关资源
      最近更新 更多