JPA 自动 BigDecimal 转换
我们正在使用 MyEclipse 生成我们的 jpa 访问层.之后我们有了生成的模型和数据层访问服务.我们遇到了一些具有定义精度的字段的问题.
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
public class TestEntity{
@Column(name="DECTEST", scale = 3, precision = 13)
BigDecimal decTest;
}
现在我们创建一个 bean 并尝试保存它:
Now we create a bean and try to save it:
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.
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
问题似乎是我们的 BigDecimals 规模高于数据库中的规模.
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);
通过这种解决方法,我们手动将 BigDecimals 精度降低到数据库中的一个.
With this workaround we reduce the BigDecimals precicsion manually to the one of the database.
但是,如果数据模型发生变化,我们将不得不手动调整比例.有没有办法让我们的 jpa/hibernate 实现自动为我们进行转换?例如.设置属性.在创建 bean 的地方做这件事无论如何都是错误的.
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.
推荐答案
您可以使用自定义用户类型,也可以像这样简单地实现属性的 setter:
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.
请注意,使用 double 来初始化 BigDecimal 有点奇怪.如果您希望将 1.2
存储在 BigDecimal 中,请使用 new BigDecimal("1.2")
,您将不会使用 1.19999999999999999555910790149937383830547332763671875
初始化 BigDecimal代码>.
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
.
相关文章