JPA automatic BigDecimal conversion

18,951

You could use a custom user type, or you could simply implement the setter of the property like this:

public void setDecTest(BigDecimal decTest) {
    this.decTest = decTest.setScale(3, RoundingMode.HALF_UP));
}

This rounding would thus be encapsulated in the entity.

Note that using a double to initialize a BigDecimal is a bit strange. If you want 1.2 to be stored in the BigDecimal, use new BigDecimal("1.2"), and you won't have a BigDecimal initialized with 1.1999999999999999555910790149937383830547332763671875.

Share:
18,951
Udo Held
Author by

Udo Held

Updated on June 09, 2022

Comments

  • Udo Held
    Udo Held almost 2 years

    We are generating our jpa access layers with MyEclipse. Afterwards we have the generated models and data layer access services. We ran into some problems for some fields with a defined precision.

    Entity:

    @Entity
    public class TestEntity{
       @Column(name="DECTEST", scale = 3, precision = 13)
       BigDecimal decTest;
    
    }
    

    Now we create a bean and try to save it:

    TestEntity te = new TestEntity();
    te.setDecTest(new BigDecimal(1.2));
    
    TestEntityService.save(te);
    

    We get the following error: Caused by: com.ibm.db2.jcc.c.SqlException: [ibm][db2][jcc][t4][1037][11190] Exception occurred during BigDecimal conversion. See attached Throwable for details.

    Caused by: com.ibm.db2.jcc.a.a: [ibm][db2][jcc][converters][608][10994] Overflow occurred during numeric data type conversion of "1.1999999999999999555910790149937383830547332763671875".
    at com.ibm.db2.jcc.a.e.a(e.java:61)
    at com.ibm.db2.jcc.b.jb.a(jb.java:1772)
    ... 73 more
    

    The problem seems to be that our BigDecimals scale is higher then the one from the database.

    A working workaround is:

    TestEntity te = new TestEntity();
    
    BigDecimal decTest = new BigDecimal(1.2);
    
    te.setDecTest(decTest.setScale(3,RoundingMode.HALF_UP);
    
    TestEntityService.save(te);
    

    With this workaround we reduce the BigDecimals precicsion manually to the one of the database.

    However if the data model changes we would have to adjust the scale there manually. Is there a way to get our jpa / hibernate implementation to do that conversion for us automatically? E.g. with setting a property. Doing it at the spot where one is creating the bean would be the wrong spot to do it anyways.