Quantcast
Channel: Bank exercise with Java Spring Boot and JPA - Code Review Stack Exchange
Viewing all articles
Browse latest Browse all 2

Bank exercise with Java Spring Boot and JPA

$
0
0

I'm constructing a homework from my Spring Boot Course and so far I did the JPA layer and want to have some feedback, before start the business rules, about if the I could improve something or change a type of relationship in my app. Any suggestions will be welcome.

Here is the exercise:

"Assume we have a big legacy system and one of the parts is withdrawal processing (the process that allows to transfer money from company to employee accounts). Now we have chance to completely rewrite the system, including API change (endpoints, DTOs etc). As a techical challenge we suggest you to take it. You can do whathever you want following the acceptance criteria:

  • Use any architecture you are comfortable with
  • Use modern Java or Kotlin
  • Use Spring boot
  • Use any database SQL/NoSQL (please use embedded)
  • The code must be tested
  • The service should be easy to run (e.q. docker-compose)

Here are some business rules of the processing:

  • We have a list of users (/v1/users endpoint)
  • A user has several payment methods
  • A user can execute a withdrawal request using one of a paymentmethods
  • A withdrawal can be executed as soon as possible or be scheduled toexecute later
  • After the service receives a request it stores a withdrawal object inour DB and sends a request to a payment provider async. Note: forthis task we don't care about a transaction completion
  • We MUST 100% send notifications regarding any withdrawal status(event, email etc)"

That's my solution for the Models with JPA:

  • USER

     @Entity(name = "User") @Table(name = "user", uniqueConstraints = {@UniqueConstraint(name= "user_email_unique", columnNames = "email")}) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id", updatable=false) private Long id; @OneToMany(mappedBy="user") @Column(name = "payment_methods") private List<PaymentMethod> paymentMethods; @OneToOne(mappedBy = "user") @JoinColumn(name = "account_id", nullable = false) private Account account; @Column(name = "first_name", nullable = false, columnDefinition = "TEXT") private String firstName; @Column(name = "last_name", nullable = false, columnDefinition = "TEXT") private String lastName; @Column(name = "email", nullable = false) private String email; @Column(name = "max_withdrawal_amount", nullable = false, columnDefinition = "DOUBLE") private Double maxWithdrawalAmount; } 
  • ACCOUNT

     @Entity(name = "Account") @Table(name = "account", uniqueConstraints = { @UniqueConstraint(name = "account_account_number_unique", columnNames = "account_number") }) public class Account { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "account_id") private Long id; @OneToOne(fetch = FetchType.LAZY) @MapsId private User user; @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<Transaction> transactionList = new ArrayList<>(); @Column(name = "account_number", nullable = false) private Integer accountNumber; @Column(name = "balance", nullable = false) private double balance; }
  • PAYMENT METHOD

     @Entity(name = "PaymentMethod") @Table(name = "payment_methods") public class PaymentMethod { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "payment_methods_id") private Long id; @ManyToOne @JsonIgnore @JoinColumn(name = "user_id", nullable = false) private User user; @Column(name = "payment_name", nullable = false, columnDefinition = "TEXT") private String paymentName; }
  • TRANSACTION

    @Entity(name = "Transaction")@Table(name = "transaction")public class Transaction {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "transaction_id", updatable = false)private Long id;@Column(name = "comment", nullable = false, columnDefinition = "TEXT")private String comment;@ManyToOne@JoinColumn(name = "accountNumber")private Account account;}
  • WITHDRAWAL

    @Entity(name = "Withdrawal")@Table(name = "withdrawal")public class Withdrawal {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "withdrawals_id")private Long id;@OneToOne(fetch = FetchType.LAZY)@MapsIdprivate Transaction transaction;@ManyToOne@JsonIgnore@JoinColumn(name = "payment_methods_id", nullable = false)private PaymentMethod paymentMethod;@Column(name = "amount", nullable = false, columnDefinition = "DOUBLE")private Double amount;@Column(name = "created_at", nullable = false, columnDefinition = "DATE DEFAULT CURRENT_DATE")private Instant createdAt;@Column(name = "execute_at", nullable = false, columnDefinition = "DATE DEFAULT CURRENT_DATE")private Instant executeAt;@Enumerated(EnumType.STRING)@Column(name = "withdrawal_status", nullable = false, columnDefinition = "TEXT")private WithdrawalStatus status;}

Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596344.js" async> </script>