Spring Hibernate将多个实体映射到一个实体

Spring Hibernate将多个实体映射到一个实体,spring,spring-boot,hibernate,jpa,Spring,Spring Boot,Hibernate,Jpa,我有两种型号,账户和交易。帐户如下所示: public class Account { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private BigDecimal balance; @OneToMany(fetch = FetchType.LAZY) private List<Transaction> transactions;

我有两种型号,
账户
交易
帐户
如下所示:

public class Account {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private BigDecimal balance;

    @OneToMany(fetch = FetchType.LAZY)
    private List<Transaction> transactions;

    public Account(final BigDecimal balance) {
        this.balance = balance;
        this.transactions = new ArrayList<>();
    }

    public void addTransaction(Transaction transaction) {
        this.transactions.add(transaction);
    }
}
public class Transaction {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Integer id;

    @OneToOne(fetch=FetchType.LAZY)
    private Account sender;

    @OneToOne(fetch=FetchType.LAZY)
    private Account recipient;

    private BigDecimal amount;

    public Transaction(Account sender, Account recipient, BigDecimal amount) {
        this.sender = sender;
        this.recipient = recipient;
        this.amount = amount;
    }
}
如您所见,
交易
是介于
发送方
接收方
之间的,这两者都由
账户
实体表示。在这种情况下,
事务
将对发送方和接收方进行一对一映射。然而,另一方面,
帐户
实体应该能够表示来自帐户的所有交易,而不管它是发送方还是接收方。使用上面的映射允许我插入事务,但是我无法将其恢复到映射中。本质上,我不确定在这种情况下最好使用什么注释

我应该补充一点,使用上述代码,我得到了以下hibernate错误:

Caused by: org.hibernate.AnnotationException: A Foreign key refering com.xxx..Account from com.xxx.Transaction has the wrong number of column. should be 1

我假设一个
账户可以是多笔交易的发送方/接收方:

  • 发送方和接收方实际上是一个
    @manytone

    public class Transaction {
     @Id
     @GeneratedValue(strategy= GenerationType.AUTO)
     private Integer id;
    
     @ManyToOne(fetch=FetchType.LAZY, optional = false)
     private Account sender;
    
     @ManyToOne(fetch=FetchType.LAZY, optional = false)
     private Account recipient;
    
     private BigDecimal amount;
    
     public Transaction(Account sender, Account recipient, BigDecimal amount {
         this.sender = sender;
         this.recipient = recipient;
         this.amount = amount;
     }
    }
    
    这是因为单个
    帐户
    可以是许多交易的发送方,但单个
    交易
    只能有一个发送方。接收器也是如此。 我还假设所有事务都必须有一个发送者和接收者

  • @OneToMany
    到两个不同的列

    您正在
    帐户
    中创建一对多,但是您希望映射
    事务
    上的关联的列是哪一列?因为有两个可能的列包含一个帐户,所以Hibernate ORM不知道使用哪个列,并抛出异常

  • 帐户中删除关联可以解决您的问题:

    public class Account {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id;
    
        private BigDecimal balance;
    
        public Account(final BigDecimal balance) {
            this.balance = balance;
        }
    }
    
    当您需要特定帐户的所有事务时,可以运行以下JPQL查询。例如,使用EntityManager:

    entityManager
        .createQuery("FROM Transaction t WHERE t.sender=:account OR t.recipient=:account")
        .setParameter("account", account )
        .getResultList();
    

    我将完全省略关系的
    Account.transactions
    端,并使用类似于
    的内容从事务t中选择t,其中t.sender=:Account或t.receiver=:Account
    (JPQL)获取帐户的事务。但是,这是有意义的,我尝试了另一种方法,即在
    事务中的发送者和接收者上都有
    @OneToOne
    映射,而在
    帐户中创建了两个列表:
    @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy=“sender”)列出发件人交易记录
    ,收件人交易记录也是如此。在本例中,我随后创建了一个临时字段,在查询
    Account
    中的所有事务时将这两个列表组合在一起,这似乎工作正常。但是,我想知道这样做是否是一种好的做法,或者按照建议只进行一个映射……您需要两个单独的查询,然后必须组合结果。通过对数据库进行一次查询,似乎可以避免很多额外的工作。但这取决于你。如果一个帐户可以是多个交易的发送方/接收方,则仍需要将映射更改为
    @ManyToOne
    (而不是
    @OneToOne
    )。