'What is the point of @JoinColumn in hibernate?

I know that @JoinColumn is used for creating the foreign key column, but my question is little bit another. I noticed that if I have main entity with mapped by and dependent entity with no @JoinColumn, than the hibernate creates two tables correctly anyway.

For example, I have Passport ans Person:

@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;
}

Passport entity:

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

}

In the both ways (with or without @JoinColumn annotation) hibernte creates the following tables:

Person table:

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

Passport table:

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

So what's the point of @JoinColumn annotation if there's no difference?



Solution 1:[1]

@JoinColumn indicates that this entity is the owner of the relationship, that the corresponding table has a column with a foreign key to the referenced table.
@JoinColumn annotation is not mandatory. If you will not specify it framework will perform default configuration instead. Hibernate and JPA follows convention over configuration. This means that the developer only needs to specify not standard aspects some custom definitions.
In case of @JoinColumn, the default column name will be generated like: [field_name]_[id_column_name].
In your case:
[field_name] - is person field of Passport entity.
[id_column_name] - is @Id column of related entity. It is id field of Person entity.

According to 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.


So if you need to override the default convention then that's exactly what @JoinColumn is for.
It covering:

  • specify the name of the foreign key column
  • specify the name of the column referenced by this foreign key column
  • specify column definition
  • specify or control the generation of a foreign key definition
  • specify the name of the table that contains the column
  • whether the property is a unique key
  • whether the column is included in SQL UPDATE statements generated by the persistence provider

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1