使用Hibernate将BigDecimal存储到H2时丢失精度

时间:2013-04-29 23:18:38

标签: java database hibernate jpa h2

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

字段定义如下所示

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

所以1.456被截断为1.46。

我不知道前面的精度(每个实体都不同),所以我不能在注释上定义它们。

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

2 个答案:

答案 0 :(得分:3)

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

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

我通过使用调试器逐步通过Hibernate源代码找到了这个,同时尝试找到my own question的答案。

似乎ResultSet方法的某些实现将使用数据库模式中定义的精度/比例,或者将尝试通过仅定义所需的最小精度/比例来优化返回的getBigDecimal保留检索到的值。

另请参阅my question here和此other question

答案 1 :(得分:0)

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

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

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

spring.jpa.hibernate.ddl-auto=none

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