如何使用JPA(EclipseLink)在DB中存储类似13.50的BigDecimal



我想使用JPA(EclipseLink(将一笔金额,比如13.50存储到数据库中。

我宣布该字段为

private BigDecimal amout;

没有进一步的注释。此字段在Sybase DB中创建为NUMERIC

当我存储一个BigDecimal.valueOf(13.50D)时,在数据库中,我在数据库字段中只得到13.00。缺少0.50。

该列也将支持13.50,我可以手动输入它。如何将13.50写入数据库字段?我需要调整BigDecimal值吗?还是需要为列设置任何精度注释?

为了使问题更加清楚,下面是一些代码片段。

这是DDL:

CREATE TABLE "DBA"."BUCH" (
"PNR" INTEGER NOT NULL DEFAULT AUTOINCREMENT,
"AMOUNT" NUMERIC(38,2) NOT NULL,
PRIMARY KEY ( "PNR" ASC )
) IN "system";

这是实体

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@Entity
@ToString
@EqualsAndHashCode
@Table(name = "BUCH")
public class Buch {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int pnr;
@Column(nullable = false, precision = 4, scale = 2))
private BigDecimal amount;
public Buch() {
// JPA
}
}

这是对它的测试

@Test
public void test()  {
Buch b = new Buch();

BigDecimal amount = new BigDecimal("13.50");
b.setAmount(amount);
assertThat(b.getAmount(), is(new BigDecimal("13.50")));
EntityManager em = createEntityManager();
em.getTransaction().begin();
em.persist(b);
em.flush();
em.getTransaction().commit();
em.close();
List<Buch> allBuch = BuchDAO.getInstance().findAll();
assertThat(allBuch.size(), is(1));
Buch buch = allBuch.get(0);
assertThat(buch.getAmount(), is(new BigDecimal("13.50")));
}

这是的测试结果

java.lang.AssertionError: 
Expected: is <13.50>
got: <13,00>

引用DECIMAL的文档(NUMERIC与Sybase中的DECIMAL相同(…

一个带符号的十进制数,具有精确的总位数,小数点后的位数为小数位数。精度可以等于1到126,刻度可以等于0到精度值。

所以零的小数位数实际上只是整数,小数部分为零。

默认值为小数位数=38,精度=126。

对于您的数据示例,默认值当然足够了。

结果是根据列的实际数据类型计算的,以确保准确性,但您可以使用MAX_CLIENT_NUMERIC_scale选项设置返回到应用程序的结果的最大比例。

所以你应该在我们的数据库中检查两件事:

  • 列定义上设置的精度和比例
  • MAX_CLIENT_NUMERIC_SCALE选项的值