Pavel
Pavel

Reputation: 115

Spring @Transactional method issue

So, I have a controller [POST] method which is basically supposed to create a transaction

Logic is simple, while creating transaction two accounts should be involved(this is scenario), into transaction I am passing 3 fields - amount, emitterId and receptorId. After the transaction is being created, the senderBalance should be decreased by transaction.amount and receiverBalance should be increased by transaction.amount, but for some reason nothing changes

Here's the code:

@Autowired
    private AccountRepository accountRepository;

    @Autowired
    private TransactionRepository transactionRepository;

@Transactional
    @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(result.getSenderAccountId()).get().getBalance();
        Integer receptorBalance = accountRepository.findById(result.getReceiverAccountId()).get().getBalance();
        Integer amount = transactionRepository.findById(result.getId()).get().getAmount();
        Integer emitterFinalBalance = emitterBalance - amount;
        Integer receptorFinalBalance = receptorBalance + amount;
        accountRepository.findById(result.getSenderAccountId()).get().setBalance(emitterFinalBalance);
        accountRepository.findById(result.getReceiverAccountId()).get().setBalance(receptorFinalBalance);
        transactionRepository.save(result);
        transactionRepository.save(transaction);
        return ResponseEntity.created(location).build();
    }

Entities Transaction

public class Transaction {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private Integer amount;
    private Instant created;
    private Long senderAccountId;
    private Long receiverAccountId;

    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "emitterId")
    private Account emitterId;

    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "receptorId")
    private Account receptorId;

    public Transaction(Integer amount, Account emitterId, Account receptorId){
        this.created = Instant.now();
        this.amount = amount;
        this.emitterId = emitterId;
        this.receptorId = receptorId;
        senderAccountId = this.emitterId.getId();
        receiverAccountId = this.receptorId.getId();
    }

}

Account

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;
    }

}

Could You help me to fix this issues, please :)?

Thank You in advnace!

Upvotes: 0

Views: 226

Answers (2)

i.bondarenko
i.bondarenko

Reputation: 3572

Try following:

    accountRepository.findById(result.getSenderAccountId()).get().setBalance(emitterFinalBalance);

accountRepository.findById(result.getReceiverAccountId()).get().setBalance(receptorFinalBalance);

replace with

Account sender = accountRepository.findById(result.getSenderAccountId()).get();
sender.setBalance(emitterFinalBalance);
accountRepository.save(sender);

Account receiver = accountRepository.findById(result.getReceiverAccountId()).get();
receiver.setBalance(receptorFinalBalance);
accountRepository.save(receiver);

Upvotes: 1

Harshal Khachane
Harshal Khachane

Reputation: 266

Looks like you are not persisting account objects on which you update balance. Do you have entity mapping from transaction to individual account with cascade so that once transaction is saved corresponding accounts objects are also persisted.

Upvotes: 2

Related Questions