使用Oracle 10g时,Hibernate对浮点列的模式validation的已知问题有哪些最佳解决方法?

我有几个带有双字段的Java类,我通过Hibernate持久化。 例如,我有

@Entity public class Node ... private double value; 

当Hibernate的org.hibernate.dialect.Oracle10gDialect为Node表创建DDL时,它会将value字段映射为“double precision”类型。

 create table MDB.Node (... value double precision not null, ... 

看起来在Oracle中,“double precision”是“float”的别名。 因此,当我尝试使用org.hibernate.cfg.AnnotationConfiguration.validateSchema()方法validation数据库模式时,Oracle似乎将值列描述为“float”。 这会导致Hibernate抛出以下exception

 org.hibernate.HibernateException: Wrong column type in DBO.ACL_RULE for column value. Found: float, expected: double precision 

Hibernate的JIRA数据库中列出了一个非常类似的问题,如HHH-1961 。 我想避免做任何会破坏MySql,Postgres和Sql Server支持的事情,因此扩展Oracle10gDialect似乎是HHH-1961中提到的最有希望的解决方法。 但延伸一个方言是我以前从未做过的事情,我担心可能会有一些讨厌的问题。 这个问题的最佳解决方法是什么,不会破坏我们与MySql,Postgres和Sql Server的兼容性?

这是模式validation器的已知限制 ,请查看HHH-2315 。 所以你在这里有三个选项(实际上是四个,但我想不需要停用validation)。 或者:

  • 在Java级别使用float而不是double – 但这可能不是一个选项。

  • 修补org.hibernate.mapping.Table.validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo)为这个特殊情况添加特殊条件 – 这实际上不是一个轻量级选项。

  • 扩展org.hibernate.dialect.Oracle10gDialect以使其为SQL类型DOUBLE使用float

     public class MyOracle10gDialect extends Oracle10gDialect { public MyOracle10gDialect() { super(); } protected void registerNumericTypeMappings() { super.registerNumericTypeMappings(); registerColumnType( Types.DOUBLE, "float" ); } } 

后一个选项似乎是安全的,但需要进行一些测试才能看出它是否没有引入任何回归。 我没有查看Oracle的JDBC驱动程序代码,所以我不能说floatdouble precision在驱动程序级别上有何不同。

只需添加(columnDefinition =“NUMBER(9,2)”)就行了!

 @Column(name = "CREDIT_AMOUNT", columnDefinition = "NUMBER(9,2)") @Basic private double creditAmount; 

HHH-1598与布尔字段的HSQL映射存在类似的问题,并在此讨论它。

我选择使用的解决方案在上面引用的讨论中,扩展了HSQLDialect。

我没有看到这个问题,尽管我只在测试中使用HSQL。

它肯定不会干扰任何其他数据库。

在您的成员上使用’scale’属性。