一尘不染

使用Oracle 10g时,Hibernate对浮点列进行模式验证的已知问题的最佳解决方法是什么?

hibernate

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

@Entity
public class Node ...

  private double value;

当Hibernate
org.hibernate.dialect.Oracle10gDialect为Node表创建DDL时,它将value字段映射为“双精度”类型。

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

在Oracle中,“双精度”似乎是“浮点数”的别名。因此,当我尝试使用该org.hibernate.cfg.AnnotationConfiguration.validateSchema()方法验证数据库架构时,Oracle似乎将value列描述为“
float”。这将导致Hibernate抛出以下异常

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的兼容性的最佳解决方法是什么?


阅读 226

收藏
2020-06-20

共1个答案

一尘不染

这是架构验证器的已知限制,请检查HHH-2315。因此,这里有三个选项(实际上是四个),但我想不要取消验证。要么:

  • 在Java级别使用a float代替double-但这可能不是一个选择。

  • org.hibernate.mapping.Table.validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo)为这种特殊情况添加补丁以添加特殊条件-这实际上不是一个明智的选择。

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

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

    }

后面的选项看似安全,但是需要进行一些测试,以查看它是否不会带来任何回归。我没有查看Oracle的JDBC驱动程序代码,因此无法说出驱动程序级别的方式floatdouble precision不同之处。

2020-06-20