有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在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


共 (2) 个答案

  1. # 1 楼答案

    这不是Oracle数据库、Java BigInteger或hibernate的问题,因为它们支持超过201910151421550246个数字

    在web应用程序上下文中,值大于数字。对于浏览器,最大安全整数不可靠

    比如我们打印控制台的时候。日志(201910151421550246);在javascript中,我们得到201910151421550240作为输出

    所以,如果你想使用大于数字的数字。打开MAX_SAFE_INTEGER,然后将其转换为字符串,然后使用它

  2. # 2 楼答案

    要点的第一行是线索。您正在用文字“D”后缀定义一个Double,而Double不能准确地表示您想要的整数。见“Floating-Point Literals”。当强制转换为BigInteger时,会出现舍入错误。使用字符串创建BigInteger,或者对于文本,使用双任务G suffix,它同时适用于BigInteger和BigDecimal

    groovy:000> i=201910151421550246D
    ===> 2.0191015142155024E17
    groovy:000> i.class
    ===> class java.lang.Double
    groovy:000> j=(BigInteger)i
    ===> 201910151421550240
    groovy:000> j.class
    ===> class java.math.BigInteger
    groovy:000> id = new BigInteger("201910151421550246")
    ===> 201910151421550246
    groovy:000> id.class
    ===> class java.math.BigInteger
    groovy:000> b=201910151421550246G
    ===> 201910151421550246
    groovy:000> b.class
    ===> class java.math.BigInteger
    groovy:000> id==b
    ===> true
    groovy:000> d=100.0G
    ===> 100.0
    groovy:000> d.class
    ===> class java.math.BigDecimal