在Hibernate中检索用BigInteger映射的属性时出现java问题
我遇到了一个关于使用Hibernate检索10^18位数字的问题。虽然我不能完全确定这是Oracle数据库问题,但Grails、Hibernate还是Java问题。考虑到这个Grails域类:
class Payment {
BigInteger id
BigDecimal amount
static mapping = {
id generator: "assigned"
version false
}
}
我通过检索遇到了这个问题:
Payment savePayment() {
BigInteger id = 201910151421550246D
BigDecimal amount = 100.00G
Payment payment = new Payment()
payment.id = id
payment.amount amount
payment.save(flush: true)
Payment retrievedPayment = Payment.findById(id)
println "payment.id: " + payment.id
println "payment.amount: " + payment.amount
println "retrievedPayment.id: " + retrievedPayment.id
println "retrievedPayment.amount: " + retrievedPayment.amount
// payment.id: 201910151421550246
// payment.amount: 100.00
// retrievedPayment.id: 201910151421550240
// retrievedPayment.amount: 100.00
return retrievedPayment
}
在保存之前,我将201910151421550246
指定为id,并确认了它在数据库中的值是否相同。的确如此。另外,当我试图使用该id
检索所述记录时,我仍然可以检索相同的Payment
记录。问题是为什么该值偏离了六个点?我目前正在将它映射到String
数据类型,并在需要执行数值操作作为临时解决方案时将其转换为BigInteger
# 1 楼答案
这不是Oracle数据库、Java BigInteger或hibernate的问题,因为它们支持超过201910151421550246个数字
在web应用程序上下文中,值大于数字。对于浏览器,最大安全整数不可靠
比如我们打印控制台的时候。日志(201910151421550246);在javascript中,我们得到201910151421550240作为输出
所以,如果你想使用大于数字的数字。打开MAX_SAFE_INTEGER,然后将其转换为字符串,然后使用它
# 2 楼答案
要点的第一行是线索。您正在用文字“D”后缀定义一个Double,而Double不能准确地表示您想要的整数。见“Floating-Point Literals”。当强制转换为BigInteger时,会出现舍入错误。使用字符串创建BigInteger,或者对于文本,使用双任务G suffix,它同时适用于BigInteger和BigDecimal