Java 对于Hibernate';使用Oracle 10g时浮点列的架构验证?

Java 对于Hibernate';使用Oracle 10g时浮点列的架构验证?,java,oracle,hibernate,orm,Java,Oracle,Hibernate,Orm,我有几个带有双字段的Java类,我正在通过Hibernate持久化这些类。例如,我有 @Entity public class Node ... private double value; 当Hibernate的org.Hibernate.dialogue.Oracle10gDialogue为节点表创建DDL时,它将值字段映射为“双精度”类型 在Oracle中,“双精度”似乎是“浮点”的别名。因此,当我尝试使用org.hibernate.cfg.AnnotationConfigurati

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

@Entity
public class Node ...

  private double value;
当Hibernate的
org.Hibernate.dialogue.Oracle10gDialogue
为节点表创建DDL时,它将值字段映射为“双精度”类型

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

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

Hibernate的JIRA数据库中列出了一个非常类似的问题。我希望避免做任何会破坏MySql、Postgres和Sql Server支持的事情,因此扩展
Oracle10gDialogue
似乎是本文中提到的最有希望的解决方法。但是扩展方言是我以前从未做过的事情,我担心可能会有一些令人讨厌的陷阱。对于这个问题,最好的解决方法是什么,它不会破坏我们与MySql、Postgres和Sql Server的兼容性

布尔字段的HSQL映射也存在类似的问题,并对此进行了讨论

我选择使用的解决方案在上面提到的讨论中,扩展了HSQLATIONAL

虽然我只在测试中使用HSQL,但我认为这没有问题

它当然不会干扰任何其他数据库。

这是模式验证器的一部分,请检查。所以这里有三个选项(实际上有四个,但我想不需要停用验证)。要么:

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

  • 修补程序
    org.hibernate.mapping.Table.validateColumns(方言、映射映射、TableMetadata tableInfo)
    为这种特殊情况添加一个特殊条件-这不是一个简单的选项

  • 扩展
    org.hibernate.dialent.oracle10galent
    ,使其对SQL类型
    DOUBLE
    使用
    float

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

后一种选择似乎是安全的,但需要进行一些测试,看看它是否不会引入任何回归。我没有看Oracle的JDBC驱动程序代码,所以我不能说
float
double-precision
在驱动程序级别有什么不同。

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

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


按照您描述的方式扩展Oracle10g方言可以修复验证问题,并且不会导致任何其他问题。谢谢@杰森,不客气。顺便说一句:识别一个好答案的常用方法是向上投票;-)这其实是最好的答案!这是可行的,但如果你只打算与Oracle合作。如果您想要更改基础数据库,或者必须支持多个数据库,那么它将无法工作。你必须把它加到模型中的每一个双字段中。所以不,不是最好的答案。
public class MyOracle10gDialect extends Oracle10gDialect {
    public MyOracle10gDialect() {
        super();
    }
    protected void registerNumericTypeMappings() {
        super.registerNumericTypeMappings();
        registerColumnType( Types.DOUBLE, "float" );
    }
}
@Column(name = "CREDIT_AMOUNT", columnDefinition = "NUMBER(9,2)")
@Basic
private double creditAmount;