【问题标题】:lost precision when storing BigDecimal into H2 using Hibernate使用 Hibernate 将 BigDecimal 存储到 H2 时丢失精度
【发布时间】:2013-04-29 23:18:37
【问题描述】:

我们使用 H2 数据库进行测试,但是当我使用 Hibernate 将 BigDecimal 值存储到其中然后将其加载回来时,该值被截断到小数点后两位:

字段定义如下所示

@Column(name = "Rate", nullable = true)
private BigDecimal rate;

所以 1.456 被截断为 1.46。

我不知道预先的精度(每个实体都不同),所以我无法在注释上定义它们。

有什么办法可以解决这个问题吗?

【问题讨论】:

  • 我认为 Hibernate 正在生成模式,对吧?
  • 如果创建的列没有精度和比例,则 H2 不会截断。因此,要么使用精度/比例创建列,要么使用 Hibernate,或者您的应用程序截断该值。但是我不能说它是哪一个。
  • 能否通过在H2数据库中执行SQL语句SCRIPT得到这个数据库的schema?
  • 我认为这将是创建脚本(谢谢),很快就会验证它
  • 曾经找到答案吗?我们也遇到了这个问题。

标签: java database hibernate jpa h2


【解决方案1】:

即使您事先不知道精度/比例,我认为您仍然需要在@Column 注释中定义最大 精度和比例。您需要查看生成的数据库模式以了解 Hibernate 是如何定义列的。

顺便说一句,我可以告诉你,从数据库返回的 BigDecimal 值的创建是由专有 JDBC 驱动程序实现特定于数据库的 ResultSet 子类的 getBigDecimal 方法完成的.

我通过调试器单步调试 Hibernate 源代码发现了这一点,同时试图找到my own question 的答案。

似乎getBigDecimal 方法的某些实现将使用数据库架构中定义的精度/比例,或者将尝试通过仅定义保持该值所需的最小精度/比例来优化返回的BigDecimal已取回。

另请参阅my question here 和此other question

【讨论】:

    【解决方案2】:

    我们遇到了与此处描述的情况非常相似的情况,但问题的部分原因在于我们管理环境的方式。我们使用 Spring Data JPA(使用 Hibernate),但使用 Flyway 管理我们的架构迁移。

    与 Postgres 交互时,一切都很好,但在使用 H2 进行测试时,我们所有的 DECIMAL 类型都被持久化到数据库中,只有两位数的四舍五入(一半),没有明显的原因。

    在我们的例子中,通过在我们的 Spring Boot application.properties 中设置这个标志来解决问题:

    spring.jpa.hibernate.ddl-auto=none

    因此,根本原因是 Hibernate 应用的 DDL 生成的 JPA 定义不完整。我们的解决方案是禁用自动 DDL 生成,因为我们使用 SQL 脚本来处理它,但这也应该可以通过更完整的 JPA 定义来解决。

    【讨论】:

      猜你喜欢
      • 2020-05-02
      • 1970-01-01
      • 2011-08-09
      • 2013-02-03
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 2012-05-13
      • 2019-10-23
      相关资源
      最近更新 更多