@JoinColumn 在休眠中有什么意义?

What is the point of @JoinColumn in hibernate?

我知道 @JoinColumn 用于创建外键列,但我的问题有点不同。 我注意到,如果我有带 mapped by 的主实体和不带 @JoinColumn 的从属实体,那么 hibernate 无论如何都会正确创建两个 table。

例如,我有护照 ans 人:

@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@Data
@Entity

public class Person {
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id;
    @NonNull
    private String name;
    @NonNull
    private int age;
    @OneToOne(mappedBy = "person") 
    Passport passport;
}

护照实体:

@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
@Data
@Entity

public class Passport {
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id;
    @NonNull
    private int series;
    @NonNull
    private int number;

    @OneToOne
//    @JoinColumn(name = "person_id") //with or without this line the hibernate creates person_id in the Passport table
    @ToString.Exclude
    Person person;

}

在这两种方式中(有或没有 @JoinColumn 注释)hibernte 创建以下 tables:

人table:

###################
id ## name ## age #
###################

护照table:

#####################################
id ## series ## number ## person_id #
#####################################

如果没有区别,@JoinColumn注解有什么意义呢?

@JoinColumn 表示此实体是关系的所有者,相应的 table 有一个列,其中包含引用的 table 的外键。
@JoinColumn 注释不是强制性的。如果您不指定它,框架将改为执行默认配置。 Hibernate 和 JPA 遵循 convention over configuration。这意味着开发人员只需要指定一些自定义定义的非标准方面。
@JoinColumn 的情况下,将生成默认列名称:[field_name]_[id_column_name]
你的情况:
[field_name] - 是 Passport 实体的 person 字段。
[id_column_name] - 是相关实体的 @Id 列。它是 Person 实体的 id 字段。

根据documentation

2.2.5. Mapping entity associations/relationships
If no @JoinColumn is declared on the owner side, the defaults apply. A join column(s) will be created in the owner table and its name will be the concatenation of the name of the relationship in the owner side, _ (underscore), and the name of the primary key column(s) in the owned side.


因此,如果您需要覆盖默认约定,那么这正是 @JoinColumn 的用途。
它涵盖:

  • 指定外键列的名称
  • 指定此外键列引用的列的名称
  • 指定列定义
  • 指定或控制外键定义的生成
  • 指定包含列
  • 的table的名称
  • 属性是否是唯一键
  • 该列是否包含在 SQL 持久性提供程序生成的 UPDATE 语句中