java - 关于创建交易的 Controller 方法问题

标签 java spring hibernate h2

嘿嘿大家! :)

我有以下场景 两个表 - AccountTransaction 想法很简单 - 在两个帐户之间创建交易时(场景是只涉及 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/

相关文章:

java - JPA - "no Metadata found for type"异常

spring - spring boot 1.5.2中eureka客户端如何找到eureka服务器?

spring - Transaction readonly=true 提交事务时不抛出异常

java - 同一个请求的不同执行时间

java - Spring MVC 与 Hibernate; getCurrentSession() 时嵌套异常为 java.lang.NullPointerException

java - 如果循环在关闭对话框后不会执行(第一次使用java)Java/Android

java - Apache 负载均衡器与纯 java 应用程序

java - Hazelcast L2 缓存慢

java - Liquibase Maven : Cannot find changelog location when spring-boot starts

hibernate - 用于组合外键上的表的Grails语法