提问人:Jason 提问时间:7/1/2023 更新时间:7/1/2023 访问量:119
[Spring Data JPA]:@Column(scale)参数无效
[Spring Data JPA]: @Column(scale) parameter has no effect
问:
我有以下 DAO,它应该对银行账户进行建模。
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "ACCOUNT")
public class AccountDao {
@Id
@Column(name = "id", nullable = false)
private String id;
@Column(name = "balance", scale = 2)
private Double balance;
@Column(name = "currency")
@Enumerated(EnumType.STRING)
private Currency currency;
@Column(name = "created_at")
private Date createdAt;
// equals(), hashcode()
}
(我知道对于余额,最好使用 BigDecimal
而不是 Float
或 Double
,并且它会在下一次迭代中发生。无论如何,这都不是生产级代码。
我这个 DAO 的存储库只是扩展:JPARepository<AccountDao, String>
public interface AccountRepository extends JpaRepository<AccountDao, String> {}
相关的控制器和服务类方法相对简单:
控制器开机自检端点:
@PostMapping("/newaccount")
public ResponseEntity<EntityModel<AccountDto>> postNewAccount(@RequestBody AccountDto accountDto) {
accountService.storeAccount(accountDto);
return ResponseEntity.ok(accountModelAssembler.toModel(accountDto));
}
服务方式:storeAccount()
public void storeAccount(AccountDto accountDto) throws AccountAlreadyExistsException{
Optional<AccountDao> accountDao = accountRepository.findById(accountDto.getId());
if (accountDao.isEmpty()) {
accountRepository.save(
new AccountDao(
accountDto.getId(), accountDto.getBalance(), accountDto.getCurrency(), new Date()));
} else {
throw new AccountAlreadyExistsException(accountDto.getId());
}
}
当我以下有效负载时:POST
{
"id" : "acc2",
"balance" : 1022.3678234,
"currency" : "USD"
}
我的数据库(MySQL Ver 8.0.33-0ubuntu0.20.04.2)保留了所有十进制数字,忽略了我为注释提供的选项。Double
scale = 2
@Column
mysql> select * from account where id = 'acc2';
+------+--------------+----------------------------+----------+
| id | balance | created_at | currency |
+------+--------------+----------------------------+----------+
| acc2 | 1022.3678234 | 2023-06-30 23:48:10.230000 | USD |
+------+--------------+----------------------------+----------+
为什么会这样?我在这里做错了什么(除了不使用;见上文)?BigDecimal
答:
0赞
Jason
7/1/2023
#1
事实证明,实际上我的问题很可能正是我没有使用 .根据此线程接受的答案中的注释,注释的参数不适用于字段,但适用于字段。BigDecimal
scale
@Column
Double
BigDecimal
-1赞
S.N
7/1/2023
#2
这是如下所示的答案
在此更新的 AccountDao 中,余额字段现在的类型为 BigDecimal,注释包括 和 。precision 属性表示要存储的总位数,scale 属性表示小数点右侧的位数。@Column
precision = 15
scale = 2
这是如下所示的 AccountDao
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "ACCOUNT")
public class AccountDao {
@Id
@Column(name = "id", nullable = false)
private String id;
@Column(name = "balance", precision = 15, scale = 2)
private BigDecimal balance;
@Column(name = "currency")
@Enumerated(EnumType.STRING)
private Currency currency;
@Column(name = "created_at")
private Date createdAt;
// equals(), hashcode()
}
评论
0赞
Jason
7/1/2023
为了弄清楚这是如何工作的,从理论上讲,非常大的数字,即超过 13 个非十进制数字,可能会被截断或溢出,对吗?
0赞
S.N
7/3/2023
@Jason 你测试过吗?它有效吗?
0赞
Jason
7/4/2023
是的,我只使用了该参数,并且它根据需要持续存在。谢谢。scale
评论