Home/Learn/Hibernate & JPA/@JoinColumn & @JoinTable

@JoinColumn & @JoinTable

Intermediate
Relationships

@JoinColumn customises the FK column name on the owning side; @JoinTable specifies the join table name and both FK column names for a @ManyToMany relationship.

Overview

@JoinColumn controls the foreign key column on the owning side of a relationship. Without it, Hibernate generates a column name like relationship_field_id. @JoinTable is used for @ManyToMany relationships to customise the join table name and both FK column names (joinColumns pointing to the owning entity, inverseJoinColumns pointing to the inverse entity). The owning side is the entity that holds the @JoinColumn or @JoinTable — changes to this side's collection are persisted; changes to the inverse (mappedBy) side are ignored.

@JoinColumn on @ManyToOne

Customise the FK column name and constraints on the owning side. Always set FetchType.LAZY to prevent eager loading of the parent on every query.

Java — @JoinColumn on @ManyToOne with custom FK name
@Entity
public class OrderItem {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(
        name = "order_id",          // FK column name in order_items table
        nullable = false,
        foreignKey = @ForeignKey(name = "fk_order_item_order")  // named FK constraint
    )
    private Order order;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_id", referencedColumnName = "id")
    private Product product;
}

@JoinTable for @ManyToMany

@JoinTable names the associative table and both FK columns. Always declare @ManyToMany as LAZY and use Set (not List) to avoid MultipleBagFetchException.

Java — @JoinTable for @ManyToMany
@Entity
public class Course {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
        name = "course_students",                    // join table name
        joinColumns        = @JoinColumn(name = "course_id"),   // FK to Course
        inverseJoinColumns = @JoinColumn(name = "student_id")   // FK to Student
    )
    private Set<Student> students = new HashSet<>();
}

@Entity
public class Student {

    @ManyToMany(mappedBy = "students", fetch = FetchType.LAZY)
    private Set<Course> courses = new HashSet<>();  // inverse side — not persisted here
}

@JoinColumn on @OneToOne

For @OneToOne, @JoinColumn controls which side holds the FK. The entity with @JoinColumn is the owning side. Use optional=false when the relationship is mandatory.

Java — @JoinColumn on @OneToOne owning side
@Entity
public class User {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    @JoinColumn(
        name = "profile_id",
        unique = true,
        foreignKey = @ForeignKey(name = "fk_user_profile")
    )
    private UserProfile profile;
}

// UserProfile is the inverse side — no FK column here
@Entity
public class UserProfile {
    @OneToOne(mappedBy = "profile")
    private User user;
}

Key Points to Remember

  • 1@JoinColumn controls the FK column name, nullability, and constraint name on the owning side
  • 2@JoinTable names the join table and both FK columns for @ManyToMany relationships
  • 3The owning side (has @JoinColumn / @JoinTable) is the side whose changes are persisted
  • 4The inverse side (mappedBy) is a mirror — mutations here are ignored by Hibernate
  • 5Always declare @ManyToMany with FetchType.LAZY and use Set to prevent bag fetch exceptions
  • 6referencedColumnName in @JoinColumn lets you FK to a non-PK unique column

Interview Questions

Sign in to ask Aria
1

What is the owning side of a bidirectional relationship and why does it matter?

MediumTCS
2

How does @JoinTable differ from @JoinColumn?

EasyInfosys
3

Why should @ManyToMany use Set instead of List?

HardAmazon
4

What happens if you modify only the mappedBy (inverse) side of a relationship?

HardWipro
5

How do you name a foreign key constraint with JPA annotations?

MediumAccenture

Ask Aria about @JoinColumn & @JoinTable

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…