嘿嘿大家! :)
我有以下场景
两个表 - Account
和 Transaction
想法很简单 - 在两个帐户之间创建交易时(场景是只涉及 2 个帐户)
- sender new balance = senderAccountBalance - transactionAmount
- receiver new balance = receiverAccountBalance + transactionAmount
(我正在扩展 JpaRepositories)
执行 @PostMapping("/transactions")
方法既不会更改 SenderAccount Balance
属性,也不会更改 ReceiverAccount Balance
属性 - 这是Controller
方法和 Entities
的代码
我需要修复此选项或找到另一个选项,因为我现在有点卡住了:{
@PostMapping("/transactions")
public ResponseEntity<Transaction> createTransaction(@Valid @RequestBody Transaction transaction) {
final Transaction result = transactionRepository.save(transaction);
final URI location = ServletUriComponentsBuilder.fromCurrentRequest().
path("/{id}")
.buildAndExpand(result.getId()).toUri();
Integer emitterBalance = accountRepository.findById(transaction.getSenderAccountId()).get().getBalance();
Integer receptorBalance = accountRepository.findById(transaction.getReceiverAccountId()).get().getBalance();
Integer amount = transactionRepository.findById(transaction.getId()).get().getAmount();
Integer emitterFinalBalance = emitterBalance - amount;
Integer receptorFinalBalance = receptorBalance + amount;
accountRepository.findById(transaction.getSenderAccountId()).get().setBalance(emitterFinalBalance);
accountRepository.findById(transaction.getReceiverAccountId()).get().setBalance(receptorFinalBalance);
return ResponseEntity.created(location).build();
}
帐户.类
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String holder;
@NotNull
private Integer balance;
@OneToMany(mappedBy = "emitterId",fetch = FetchType.LAZY,cascade = CascadeType.ALL)
private List<Transaction> transactionsMade;
@OneToMany(mappedBy = "receptorId",fetch = FetchType.LAZY,cascade = CascadeType.ALL)
private List<Transaction> transactionsReceived;
public Account(String holder, Integer balance){
this.holder = holder;
this.balance = balance;
}
public Account(Long id){
this.id = id;
}
}
交易.类
public class Transaction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private Integer amount;
@NotNull
private Instant created;
@NotNull
private Long senderAccountId;
@NotNull
private Long receiverAccountId;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "emitterId")
private Account emitterId;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "receptorId")
private Account receptorId;
public Transaction(Long id,Integer amount, Account emitterId, Account receptorId){
this.created = Instant.now();
this.amount = amount;
this.emitterId = emitterId;
this.receptorId = receptorId;
this.id = id;
senderAccountId = this.emitterId.getId();
receiverAccountId = this.receptorId.getId();
}
}
你能帮我解决这个问题吗? 提前谢谢您! :)
最佳答案
只需将您的方法标记为@Transactional
。
如果没有,存储库会返回处于分离状态的实体(不会跟踪修改),并且要保存修改,您必须通过调用repository.save(entity) 显式保存它们
。像这样:
@PostMapping("/transactions")
public ResponseEntity<Transaction> createTransaction(@Valid @RequestBody Transaction transaction) {
...
var senderAccount = accountRepository.findById(transaction.getSenderAccountId()).get();
senderAccount.setBalance(emitterFinalBalance);
accountRepository.save(senderAccount);
var receiverAccount = accountRepository.findById(transaction.getReceiverAccountId()).get();
receiverAccount.setBalance(receptorFinalBalance);
accountRepository.save(receiverAccount);
return ResponseEntity.created(location).build();
}
拥有一个事务方法会改变这种行为,并且存储库返回附加状态的实体,这意味着Hibernate将跟踪这些实体中的所有更改,并且所有更新都将发送到数据库上该方法结束。要实现此行为,您必须将此方法标记为 @Transactional
:
@PostMapping("/transactions")
@Transactional
public ResponseEntity<Transaction> createTransaction(@Valid @RequestBody Transaction transaction) {
...
关于java - 关于创建交易的 Controller 方法问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57737726/