[Spring Data JPA]:@Column(scale)参数无效

[Spring Data JPA]: @Column(scale) parameter has no effect

提问人:Jason 提问时间:7/1/2023 更新时间:7/1/2023 访问量:119

问:

我有以下 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 而不是 FloatDouble,并且它会在下一次迭代中发生。无论如何,这都不是生产级代码。

我这个 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)保留了所有十进制数字,忽略了我为注释提供的选项。Doublescale = 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

java spring-data-jpa 精度

评论


答:

0赞 Jason 7/1/2023 #1

事实证明,实际上我的问题很可能正是我没有使用 .根据此线程接受的答案中的注释,注释的参数不适用于字段,但适用于字段。BigDecimalscale@ColumnDoubleBigDecimal

-1赞 S.N 7/1/2023 #2

这是如下所示的答案

在此更新的 AccountDao 中,余额字段现在的类型为 BigDecimal,注释包括 和 。precision 属性表示要存储的总位数,scale 属性表示小数点右侧的位数。@Columnprecision = 15scale = 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