我有几个带有双字段的Java类,这些都是通过Hibernate持久化的。例如,我有
@Entity public class Node ... private double value;
当Hibernate org.hibernate.dialect.Oracle10gDialect为Node表创建DDL时,它将value字段映射为“双精度”类型。
org.hibernate.dialect.Oracle10gDialect
create table MDB.Node (... value double precision not null, ...
在Oracle中,“双精度”似乎是“浮点数”的别名。因此,当我尝试使用该org.hibernate.cfg.AnnotationConfiguration.validateSchema()方法验证数据库架构时,Oracle似乎将value列描述为“ float”。这将导致Hibernate抛出以下异常
org.hibernate.cfg.AnnotationConfiguration.validateSchema()
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支持的事情,因此扩展HHH-1961中Oracle10gDialect提到的变通办法似乎是最有希望的。但是扩展方言是我以前从未做过的事情,而且恐怕可能会遇到一些麻烦。不会破坏我们与MySql,Postgres和Sql Server的兼容性的最佳解决方法是什么?
Oracle10gDialect
这是架构验证器的已知限制,请检查HHH-2315。因此,这里有三个选项(实际上是四个),但我想不要取消验证。要么:
在Java级别使用a float代替double-但这可能不是一个选择。
float
double
org.hibernate.mapping.Table.validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo)为这种特殊情况添加补丁以添加特殊条件-这实际上不是一个明智的选择。
org.hibernate.mapping.Table.validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo)
扩展org.hibernate.dialect.Oracle10gDialect使其float用于SQL类型DOUBLE
DOUBLE
public class MyOracle10gDialect extends Oracle10gDialect { public MyOracle10gDialect() { super(); } protected void registerNumericTypeMappings() { super.registerNumericTypeMappings(); registerColumnType( Types.DOUBLE, "float" ); }
}
后面的选项看似安全,但是需要进行一些测试,以查看它是否不会带来任何回归。我没有查看Oracle的JDBC驱动程序代码,因此无法说出驱动程序级别的方式float和double precision不同之处。
double precision