【问题标题】:Bank database: correct definition of a relationship?银行数据库:关系的正确定义?
【发布时间】:2020-11-26 08:25:27
【问题描述】:

我正在使用 Spring Boot 和 Spring Data JPA 构建一个银行应用程序,其中我在定义 BankAccount 类与 BankTransfer 类之间的关系时遇到了一些问题,我找不到解决方案。一个银行账户有一个转账列表List<BankTransfer> transfers。所以这里的关系被定义为@OneToMany。但在每笔银行转账中,我都有两个 BankAccount 引用,称为“发送者”和“接收者”。发送方是提取金额的账户,接收方是添加金额的账户。

因此,每笔银行转账都必须与 BankAccount 类有@ManyToOne 关系(这种关系正是二对一关系)。那么这里的难点是如何映射两个银行账户(发送方和接收方)?在 BankAccount 类的 @OneToMany 注释中设置什么为 mappedBy 字段。

这是我的课程:

BankAccount 类:

@Entity
@Table(name = "bank_account")
public class BankAccount {
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "account_Sequence")
    @SequenceGenerator(name = "account_Sequeence", sequenceName = "BANK_ACCOUNT_SEQ")
    @Column(name ="id")
    private Long id;

    @NotNull
    @Column(name ="account_number")
    private String accountNumber;

    @NotNull
    @Enumerated
    @Column(name ="type")
    private AccountType type;

    @Column(name ="currency")
    private Currency currency;

    @NotNull
    @Column(name ="balance")
    private BigDecimal balance;

    @NotNull
    @Column(name ="date_created")
    protected Date dateCreated;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE,
                          CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name="client_id")
    protected Client client;

    @Column(name ="employee_id")
    private Employee accountManager;

    @OneToMany(fetch = FetchType.LAZY,
               mappedBy = "sender",
               cascade = {CascadeType.PERSIST, CascadeType.MERGE,
                          CascadeType.DETACH, CascadeType.REFRESH})
    protected List<BankTransfer> transfers;
}

还有 BankTransfer 类:

@Entity
@Table(name="transfer")
public class BankTransfer {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "transaction_Sequence")
    @SequenceGenerator(name = "transaction_Sequeence", sequenceName = "TRANSACTION_SEQ")
    private Long id;
    
    @NotNull
    @Column(name = "amount")
    private BigDecimal amount;

    @NotNull
    @ManyToOne(targetEntity = BankAccount.class,
               fetch = FetchType.LAZY,
               cascade = {CascadeType.PERSIST, CascadeType.MERGE,
                           CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name = "sender_id")
    private BankAccount sender;

    @NotNull
    @ManyToOne(targetEntity = BankAccount.class,
               fetch = FetchType.LAZY,
               cascade = {CascadeType.PERSIST, CascadeType.MERGE,
                          CascadeType.DETACH, CascadeType.REFRESH})
    @JoinColumn(name = "receiver_id")
    private BankAccount receiver;

    @NotNull
    @Column(name = "created_at")
    private Date createdAt;
}

如你所见,我有:

@OneToMany(fetch = FetchType.LAZY,
                   mappedBy = "sender",
                   cascade = {CascadeType.PERSIST, CascadeType.MERGE,
                              CascadeType.DETACH, CascadeType.REFRESH})
protected List<BankTransfer> transfers;

在 BankAccount 类中尝试映射 BankTransfer 类中的 BankAccount sender 字段:

@NotNull
@ManyToOne(targetEntity = BankAccount.class,
           fetch = FetchType.LAZY,
           cascade = {CascadeType.PERSIST, CascadeType.MERGE,
                           CascadeType.DETACH, CascadeType.REFRESH})
@JoinColumn(name = "sender_id")
private BankAccount sender;

我还想在 BankTransfer 类中映射 BankAccount receiver 字段。例如,我试过这样:

mappedBy = {"sender", "receiver"},

或尝试添加 2 个 @OneToMany 注释,但这些似乎是错误的。

你能帮我解决这个问题吗?也许我需要以某种方式分别重新定义我的实体和 oracle 数据库表。我对 RDBMS 比较陌生,我正在构建这个应用程序,以便获得更多使用它们的经验。

【问题讨论】:

  • 需要将转帐分为receivedTransfers和sendTransfers。

标签: java hibernate jpa


【解决方案1】:

这取决于您如何在这些实体上填充数据。 如果新建数据库,可以创建join table,使用@OneToMany

通常在像你这样的情况下,我只在BankTransfer 端使用关系,所以你可以从BankAccount 删除转移,特别是你有惰性关系。从实体BankAccount转移可以通过sql、jpa等实现,实体中不需要字段

【讨论】:

  • 关系可以是单向的,双向的都不是问题
  • 谢谢你,我按照你的建议做了 - 在 BankTransfer 上只使用了关系,它工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 2015-12-31
相关资源
最近更新 更多