2012-08-10 32 views
3

我们正在使用MyEclipse生成我们的jpa访问层。之后,我们拥有生成的模型和数据层访问服务。我们遇到了一些确定精度的问题。JPA自动BigDecimal转换

实体:

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

} 

现在我们创建一个bean,并尝试将其保存:

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

TestEntityService.save(te); 

我们得到以下错误:由 引起:com.ibm.db2.jcc.c .SqlException:[ibm] [db2] [jcc] [t4] [1037] [11190] BigDecimal转换期间发生异常。详情请参阅附件Throwable。

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 

问题似乎是我们的BigDecimals比例高于数据库中的比例。

的工作解决方法是:

TestEntity te = new TestEntity(); 

BigDecimal decTest = new BigDecimal(1.2); 

te.setDecTest(decTest.setScale(3,RoundingMode.HALF_UP); 

TestEntityService.save(te); 

有了这个解决方法,我们减少BigDecimals的手动precicsion到数据库中的一个。

但是,如果数据模型发生变化,我们必须手动调整比例。有没有办法让我们的jpa/hibernate实现自动为我们做转换?例如。与设置属性。无论如何,在创建bean的地方做这件事是错误的地方。

回答

7

你可以使用自定义的用户类型,或者你可以简单地实现setter方法是这样的:

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

此舍入将因此在实体封装。

请注意,使用double来初始化BigDecimal有点奇怪。如果要将1.2存储在BigDecimal中,请使用new BigDecimal("1.2"),并且您将不会使用1.1999999999999999555910790149937383830547332763671875对BigDecimal进行初始化。

+0

也想到了这两个。然而,1.2仅用于测试。它来自用户界面,应该被验证为一个数字,以便没有人可以发送“hallo”而不是数字。随着访问层的生成,我不想修改它。使用几个BigDecimal属性的手动方式并不好,但是如果没有更好的方法出现,我们可能不得不去做。 – 2012-08-10 10:09:46

+1

你为我解释了一些关于不对BigDecimal的构造函数解析double的问题,让我省了些麻烦。这是我需要拒绝的诱惑。 – 2013-06-09 20:51:24