我正在使用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:此id生成器生成长整数,短整数或字符串
似乎我的序列返回Number,hibenate将其视为BigDecimal,而hibernate的sequece生成器类只考虑long,integer,short和string的值。
Hibernate应该没有BigDecimal的问题。但我认为他们没有为序列生成器实现BigDecimal
任何人都可以帮我解决问题吗?
感谢。
答案 0 :(得分:13)
老实说,我无法想象为什么你会坚持让你的ID为BigDecimal而不是长。最大长值是9,223,372,036,854,775,807
,虽然这个值大约是最大NUMBER(22)值的千分之一,但实际上应该足够。如果您要生成一个百万标识符每秒,则必须执行 300,000年,以便耗尽您的序列。
也就是说,为了让您的标识符生成为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>
答案 1 :(得分:2)
你设置了正确的方言吗?这应该足以让Hibernate理解序列的结果。
[编辑]问题是序列的类型与列的类型不匹配。当序列返回BigDecimal时,序列(根据Hibernate的错误消息)可以转换为long,integer,short或string。
我建议将ID列的类型指定为“long”,即使Oracle不知道该类型。在内部,Hibernate应该能够正确地为每个人投射所有内容。
答案 2 :(得分:2)
当然。长id必须足够考虑它可以生成的唯一记录的数量。仅具有特殊值的特定生成器可能不是整数类型,或者由于某种原因(可能是项目特定的)控制整数类型值。
此外,生成器是特定于数据库的,如oracle的序列,因此dialact定义也很重要。