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

5
我们正在使用H2数据库进行测试,但当我使用Hibernate将BigDecimal值存储到其中,然后再加载它时,该值被截断为两位小数:
字段定义如下:
@Column(name = "Rate", nullable = true)
private BigDecimal rate;

因此,1.456被截断为1.46。

我不知道精度,因为每个实体都不同,所以我无法在注释中定义它们。

有没有解决这个问题的方法?


Hibernate 会生成模式,对吧? - acdcjunior
1
如果列没有精度和比例创建,则H2不会截断。因此,要么使用精度/比例创建列,要么使用Hibernate或应用程序截断值。但是我无法确定是哪一个。 - Thomas Mueller
你能否通过在H2数据库中执行SQL语句“SCRIPT”来获取该数据库的模式? - Thomas Mueller
我假设这将是创建脚本(现在谢谢),我很快会验证它。 - Matej Tymes
你有找到解决方法吗?我们也遇到了这个问题。 - bvulaj
我在这里找到了一个有用的答案:https://dev59.com/N2_Xa4cB1Zd3GeqP7f8m - Scar Coder
3个回答

6
即使您不知道精度/比例,我认为您仍然需要在@Column注释中定义最大精度和比例。您需要查看生成的数据库模式以查看Hibernate如何定义列。
顺便说一下,我可以告诉您,从数据库返回的BigDecimal值的创建是由专有JDBC驱动程序实现的,该驱动程序实现了特定于数据库的ResultSet子类的getBigDecimal方法。
我通过使用调试器逐步浏览Hibernate源代码并尝试找到答案我的问题来发现这一点。
似乎某些getBigDecimal方法的实现将使用在数据库模式中定义的精度/比例,或者将尝试通过仅定义检索到的值所需的最小精度/比例来优化返回的BigDecimal。

还可以参考这里我的问题其他问题


1
我们遇到了一个与此类似的情况,但问题部分原因在于我们如何管理环境。我们使用Spring Data JPA(使用Hibernate),但使用Flyway来管理模式迁移。
在与Postgres交互时,一切正常,但在使用H2进行测试时,我们所有的DECIMAL类型都只保留了两位四舍五入的小数位数,没有明显的原因。
在我们的情况下,通过在Spring Boot应用程序属性中设置此标志解决了该问题:

spring.jpa.hibernate.ddl-auto=none

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

1
遇到了这个问题,尝试存储像0.08559、0.000000012这样的值,但会被存储为0.00。 必须在实体定义中使用scale + precision属性。 例如:
@Column(scale = 15, precision = 30)
private BigDecimal myValue;

记住:Precision(精度)指定数值中的总位数,Scale(刻度)指定小数点后的位数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接