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

2022-09-02 20:56:39

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

@Entity
public class Node ...

  private double value;

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

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

在Oracle中,“双精度”似乎是“float”的别名。因此,当我尝试使用该方法验证数据库架构时,Oracle似乎将值列描述为“浮点数”。这会导致休眠引发以下异常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中提到的最有希望的解决方法。但是扩展方言是我以前从未做过的事情,我担心可能会有一些令人讨厌的陷阱。对于这个问题,不会破坏我们与MySql,Postgres和Sql Server的兼容性的最佳解决方法是什么?Oracle10gDialect


答案 1

这是架构验证程序的已知限制,请检查 HHH-2315。所以你在这里有三个选择(实际上是四个,但我想不需要停用验证)。也:

  • 在 Java 级别使用 a 而不是 a - 这可能不是一个选项。floatdouble

  • 补丁为这种特殊情况添加特殊条件 - 这不是一个真正的轻量级选项。org.hibernate.mapping.Table.validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo)

  • 扩展以使其用于 SQL 类型org.hibernate.dialect.Oracle10gDialectfloatDOUBLE

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

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


答案 2

只需添加(列定义=“NUMBER(9,2)”)即可!

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

推荐