what is @JoinColumn and how it is used in Hibernate

I have been reading a lot about @JoinColumn but I still don't get the idea behind it.

Patient Table

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

Vehicle Table

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));

Patient Class

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

Vehicle Class

@ManyToOne
@JoinColumn(name="patient_id")
private Patient patient;

I'm confused on how the Vehicle class part, what is the relationship between

Vehicle Class ---- Entity
@JoinColumn(name="patient_id") ---- annotation
private Patient patient ----field

Does it say; The Vehicle Entity has a Foreign Key to Patient entity named patient_id. Add the patient_id as a column in the Vehicle Entity table

Do the name parameter of the JoinColumn should always be a Foreign Key or Primary Key?

I have been reading this but I'm still confuse. JPA JoinColumn vs mappedBy


A unidirectional association via a join table

@Entity
class Patient {

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

}

@Entity
class Vehicle {

}

A bidirectional association via a join table

@Entity
class Patient {

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

}

@Entity
class Vehicle {

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

}

A unidirectional association via a foreign key

@Entity
class Patient {

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

}

@Entity
class Vehicle {

}

A bidirectional association via a foreign key

@Entity
class Patient {

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

}

@Entity
class Vehicle {

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

}

A bidirectional association via a foreign key with a foreign column name specification

@Entity
class Patient {

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

}

@Entity
class Vehicle {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="patient_id")
    private Patient patient;

}

This is the basic starting point of using @JoinColumn.

To verify that the foreign key(patient_id in the Vehicle table) is really mapped in the patients table you can use @JoinColumn(nullable = false)

@Entity
class Vehicle {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="patient_id", nullable = false)
    private Patient patient

}

The join column is declared with the @JoinColumn annotation which looks like the @Column annotation. It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join.

In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side.

Here is Sample code :

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;