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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2625600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 20:24:18  来源:igfitidea点击:

What are the best workarounds for known problems with Hibernate's schema validation of floating point columns when using Oracle 10g?

javaoraclehibernateorm

提问by Jason Novak

I have several Java classes with double fields that I am persisting via Hibernate. For example, I have

我有几个带有双字段的 Java 类,我通过 Hibernate 保留它们。例如,我有

@Entity
public class Node ...

  private double value;

When Hibernate's org.hibernate.dialect.Oracle10gDialectcreates the DDL for the Node table, it maps the value field to a "double precision" type.

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

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

It would appear that in Oracle, "double precision" is an alias for "float". So, when I try to verify the database schema using the org.hibernate.cfg.AnnotationConfiguration.validateSchema()method, Oracle appears to describe the value column as a "float". This causes Hibernate to throw the following Exception

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

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

A very similar problem is listed in Hibernate's JIRA database as HHH-1961. I'd like to avoid doing anything that will break MySql, Postgres, and Sql Server support so extending the Oracle10gDialectappears to be the most promising of the workarounds mentioned in HHH-1961. But extending a Dialect is something I've never done before and I'm afraid there may be some nasty gotchas. What is the best workaround for this problem that won't break our compatibility with MySql, Postgres, and Sql Server?

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

回答by Pascal Thivent

This is a known limitationof the schema validator, check HHH-2315. So you have three options here (actually four but I guess that deactivating validation is not wanted). Either:

这是模式验证器的已知限制,请检查HHH-2315。因此,您在这里有三个选项(实际上是四个,但我想不需要停用验证)。任何一个:

  • Use a floatinstead of a doubleat the Java level - this might not be an option though.

  • Patch org.hibernate.mapping.Table.validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo)to add a special condition for this particular case - this isn't really a light option.

  • Extends the org.hibernate.dialect.Oracle10gDialectto make it use floatfor the SQL type DOUBLE

    public class MyOracle10gDialect extends Oracle10gDialect {
        public MyOracle10gDialect() {
            super();
        }
        protected void registerNumericTypeMappings() {
            super.registerNumericTypeMappings();
            registerColumnType( Types.DOUBLE, "float" );
        }
    }
    
  • 在 Java 级别使用 afloat而不是 a 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" );
        }
    }
    

The later option seems safe but will require some testing to see if it doesn't introduce any regression. I didn't look at Oracle's JDBC driver code, so I can't say how floatand double precisiondiffer at the driver level.

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

回答by Devashish

just adding (columnDefinition = "NUMBER(9,2)") works!

只需添加 (columnDefinition = "NUMBER(9,2)") 即可!

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

回答by Don Roby

There was a similar problem HHH-1598with HSQL mappings of boolean fields, and a discussion of it here.

有一个类似的问题HHH-1598与布尔字段的 HSQL 映射有关,并在此处进行了讨论。

The solution I chose to use was in the discussion referenced above, with an extension of HSQLDialect.

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

I saw no problems with this, though I only use HSQL in tests.

虽然我只在测试中使用 HSQL,但我没有看到这方面的问题。

It certainly doesn't interfere with any other DB.

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

回答by Shimansky

Use 'scale' attribute on your member.

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