仅使用 @mappedBy ,不使用@JoinColumn - 在 OneToMany 关系中创建的连接列,那么 JoinColumn 的用途是啥?

Posted

技术标签:

【中文标题】仅使用 @mappedBy ,不使用@JoinColumn - 在 OneToMany 关系中创建的连接列,那么 JoinColumn 的用途是啥?【英文标题】:Used only @mappedBy , no@JoinColumn - join column created in OneToMany relationship, what is then the use of JoinColumn?仅使用 @mappedBy ,不使用@JoinColumn - 在 OneToMany 关系中创建的连接列,那么 JoinColumn 的用途是什么? 【发布时间】:2019-07-17 04:51:00 【问题描述】:

我是 Hibernate 的新手。我与 Account 和 Transaction 之间的双向映射有 OneToMany 关系。我没有在任何一个类中使用 @JoinColumn 并在非拥有 Account 类中使用 @mappedBy。一切正常。使用内存数据库中的 H2,在 Transaction 表中创建新的连接列。那么在 OneToMany 关系中@JoinColumn 有什么用——它只用于单向映射吗?下面是代码。我也读了参考What's the difference between @JoinColumn and mappedBy when using a JPA @OneToMany association

  public class Account 
        @OneToMany( mappedBy="account", cascade=CascadeType.ALL)
        List<Transaction> list= new ArrayList<Transaction>();
    

    public class Transaction 

        @ManyToOne
        Account account;
    

应用类:

        Account a = new Account("savings");

        Transaction t1 = new Transaction("shoe purchase", 45);

        t1.setAccount(a);

        a.getList().add(t1);

        accountRepository.save(a);

输出:

事务表有一个外键条目,即帐户表中那一行的帐号。在 Transaction 表中创建 ACCOUNT_ID 列。

没有创建额外的表。

【问题讨论】:

【参考方案1】:

MappedBy 指示 Hibernate 用于关联的键位于关联的另一端。就像在本例中,在 Account 表上创建 ACCOUNT_ID。

这意味着尽管您将两张表关联在一起,但只有一张表对另一张表有外键约束。

MappedBy允许您仍然从没有外键约束的表关联到另一个表。

【讨论】:

在这种情况下,Account_Id 是在 Transaction 表中创建的。存在更改表事务添加约束 FK6g20fcr3bhr6bihgy24rq1r1b 外键 (account_id) 引用帐户。据我目前所知,这是它工作所需的唯一约束。 如果您不使用 Hibernate 或任何其他 ORM,则必须手动执行。 Hibernate 在内部代表您这样做,这就是美。【参考方案2】:

Jpa 致力于按照惯例进行配置。因此,它将尽可能代表您执行配置。想想@Column 注释,您不必将它应用于每个实体属性,只有在必须更改属性时才需要它。

@JoinColumn 相同,当您添加@ManyToOne 时,Jpa 已经知道您将需要连接列,因此已为您添加并应用了外键的默认命名约定 (attributename_primarykeyoftheothertype) .

【讨论】:

知道了,谢谢!事实证明,ManyToMany 也是如此——我只有 mappedBy,没有 JoinColumn,但创建了一个单独的连接表,它单独维护关系。所以相信JPA也想出来了。是的,根据另一个答案,我可以使用 JoinColumn 来更改列名,但关系本身是单独使用 mappedBy 建立的。所以只有当它是单向的时,我才需要 JoinColumn。【参考方案3】:

使用

映射人

指示框架启用双向关系。由于事务类上的@ManyToOne,您的事务表将具有引用帐户表主键的外键。默认情况下,Hibernate 根据关系映射属性的名称和主键属性的名称生成外键列的名称。在这个例子中,Hibernate 将使用名为 account_id 的列来存储 Account 实体的外键。

@JoinColum

如果您想覆盖默认外键名称,如@JoinColum(name="acc_id"),则可以使用

【讨论】:

以上是关于仅使用 @mappedBy ,不使用@JoinColumn - 在 OneToMany 关系中创建的连接列,那么 JoinColumn 的用途是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data JPA中的mappedBy

hibernate的注解属性mappedBy详解

hibernate的注解属性mappedBy详解

有人可以解释 JPA 和 Hibernate 中的 mappedBy 吗?

Hibernate中,mappedBy和注解@JoinColumn的对比

JPA:仅更新映射表