什么是@JoinColumn以及如何在Hibernate中使用它

时间:2016-05-31 09:42:33

标签: java hibernate postgresql jpa

我一直在阅读关于@JoinColumn的很多内容,但我仍然不了解它背后的想法。

患者表

CREATE TABLE patient (
patient_id BIGINT NOT NULL,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
PRIMARY KEY(patient_id));

车辆表

CREATE TABLE vehicles (
patient_id BIGINT NOT NULL,
vehicle_id BIGINT NOT NULL,
vehicle_manufacturer VARCHAR(255),
PRIMARY KEY (vehicle_id),
CONSTRAINT patienthasmanyvehicle FOREIGN KEY(patient_id) REFERENCES patient(patient_id));

患者等级

@OneToMany(mappedBy = "patient")
    private Collection<Vehicle> patientVehicles = new ArrayList<Vehicle>();

车辆类

@ManyToOne
@JoinColumn(name="patient_id")
private Patient patient;
我对于如何将Vehicle类部分,

之间的关系搞糊涂了
Vehicle Class ---- Entity
@JoinColumn(name="patient_id") ---- annotation
private Patient patient ----field

是否说; 车辆实体外键患者实体,名为 patient_id 。 将 patient_id 添加为车辆实体表

中的列

JoinColumn的name参数应该始终是外键还是主键?

我一直在读这篇文章,但我仍然感到困惑。 JPA JoinColumn vs mappedBy

5 个答案:

答案 0 :(得分:30)

通过连接表进行单向关联

@Entity
class Patient {

    @OneToMany
    private Collection<Vehicle> vehicles = new ArrayList<Vehicle>();

}

@Entity
class Vehicle {

}

通过连接表进行双向关联

@Entity
class Patient {

    @OneToMany
    private Collection<Vehicle> vehicles = new ArrayList<Vehicle>();

}

@Entity
class Vehicle {

    @ManyToOne(fetch = FetchType.LAZY)
    private Patient patient;

}

通过外键进行单向关联

@Entity
class Patient {

    @OneToMany
    @JoinColumn
    private Collection<Vehicle> vehicles = new ArrayList<Vehicle>();

}

@Entity
class Vehicle {

}

通过外键进行双向关联

@Entity
class Patient {

    @OneToMany(mappedBy = "patient")
    private Collection<Vehicle> vehicles = new ArrayList<Vehicle>();

}

@Entity
class Vehicle {

    @ManyToOne(fetch = FetchType.LAZY)
    private Patient patient;

}

这是使用@JoinColumn的基本起点。

要验证外键(patient_id表中的Vehicle)是否真正映射到患者表中,您可以使用@JoinColumn(nullable = false)

@Entity
class Vehicle {

    @JoinColumn(name="patient_id", nullable = false)
    private Patient patient

}

答案 1 :(得分:2)

车辆类----实体 @JoinColumn(name =&#34; patient_id&#34;)----注释 私人病人----现场

上面的代码将在Vehicle类中生成一列Patient_id(外键),该列将指向Patient Class主键。

MappedBy - 该属性告诉我们这个关系将由Vehicle类管理。例。如果我们插入车辆,那么如果cascadetype是全部/保存,则将注入两个SQL。第一个SQL将在Patient表中注入详细信息,第二个SQL将在车辆表中注入车辆详细信息,其中vehicles_id列的Vehicle列指向插入的患者元组。

答案 2 :(得分:1)

使用@JoinColumn注释声明连接列,该注释类似于@Column注释。它还有一个名为referencedColumnName的参数。此参数声明目标实体中将用于连接的列。

在双向关系中,其中一方(并且只有一方)必须是所有者:所有者负责更新关联列。要声明一方不对关系负责,使用属性mappedBy。 mappedBy引用所有者方的关联的属性名称。

以下是示例代码:

EntityOne : 
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEST_ID")
    private EntityTwo entityTwo;

EntityTwo : 
      // bi-directional many-to-one association to EntityOne Here TEST_ID is the Primary key
    @OneToMany(mappedBy = "entityTwo")
    private List<EntityOne> entityOne;

答案 3 :(得分:1)

将在其中找到连接列的表取决于上下文。

  • 如果该联接用于使用外键映射策略的OneToOne或ManyToOne映射,则外键列在源实体的表中或可嵌入。

  • 如果联接是使用外键映射策略进行的单向OneToMany映射,则外键在目标实体的表中。

  • 如果联接是针对使用联接表的ManyToMany映射或OneToOne或双向ManyToOne / OneToMany映射,则外键在联接表中。

  • 如果联接用于元素集合,则外键位于集合表中。

答案 4 :(得分:0)

为什么运行我的代码时,车辆表中的patient_id(生成的FK列)没有任何值?

所有@JoinColumn都是指定用于加入实体关联或元素集合的列。由于您已将@JoinColumn与Patient类对象关联起来,这就是为什么在Patient表上创建外键的原因。

有关详情,请参阅https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/JoinColumn.html