【发布时间】:2020-07-16 14:56:58
【问题描述】:
我想使用 JPA (EclipseLink) 在数据库中存储一笔钱,比如说 13.50。
我将该字段声明为
private BigDecimal amout;
没有进一步的注释。此字段在 Sybase DB 中创建为 NUMERIC。
当我在数据库中存储BigDecimal.valueOf(13.50D) 时,我只在数据库字段中得到 13,00。缺少 0.50 个。
该列也支持 13.50,我可以手动输入。 我应该怎么做才能将 13.50 写入数据库字段?是否需要调整 BigDecimal 值或 / 是否需要为列设置任何精度注释?
为了让问题更清楚,这里有一些代码sn-ps。
这是 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>
【问题讨论】:
-
原则上您输入的代码似乎没问题,您可以尝试将值初始化为 BigDecimal.valueOf (12.50);只有当它不起作用时,才将这段代码放在初始化实体的位置(或转换它的位置)以及持久化对象的方法。问候
-
顺便说一句,
BigDecimal.valueOf( 12.50D )之类的代码是错误的使用BigDecimal的方式。传递double意味着您已经引入了inaccuracy of a floating-point type,从而阻碍了使用BigDecimal的目的。改为传递String:BigDecimal.valueOf( "12.50D" ) -
列的确切类型是什么,在某些数据库中,只有
NUMERIC将具有特定于实现的精度和比例 0(尽管对于Sybase),这意味着它只接受整数。要接受 12.50,该列需要是 - 例如 -NUMERIC(9, 2)。在任何情况下,拥有minimal reproducible example 会很有帮助,包括数据库架构和您的 Java 代码。 -
打开日志记录,检查数据库中的实际内容,以确定输入或值的回读是否存在问题。
标签: java jpa eclipselink