Mapping relationships

Hibernate · lesson 7 of 32 · 5 min read

Map @ManyToOne, @OneToMany and @ManyToMany, and know which side owns the foreign key.

Open this lesson in the learning hub

Key points

  • The owning side is the one holding the foreign key column. Hibernate writes only what the owning side says.
  • @ManyToOne is nearly always the owning side and carries @JoinColumn. Its @OneToMany mirror uses mappedBy.
  • A @OneToMany without mappedBy makes Hibernate invent a join table. Rarely what you wanted.
  • Keep both sides in sync in a helper method. Adding to the collection alone changes nothing in the database.
  • @ManyToMany needs @JoinTable. Use a Set: with a List, Hibernate deletes and re-inserts every link row on any change.
  • The moment the link needs its own data (a quantity, an added-on date), replace @ManyToMany with a real join entity.

Example

@Entity
public class Author {

    @Id @GeneratedValue private Long id;
    private String name;

    @OneToMany(mappedBy = "author")     // inverse side: owns no column
    private List<Book> books = new ArrayList<>();

    public void addBook(Book book) {    // keep BOTH sides consistent
        books.add(book);
        book.setAuthor(this);
    }
}

@Entity
public class Book {

    @Id @GeneratedValue private Long id;
    private String title;

    @ManyToOne(fetch = FetchType.LAZY)  // owning side: holds author_id
    @JoinColumn(name = "author_id")
    private Author author;

    @ManyToMany
    @JoinTable(name = "book_tag",
               joinColumns = @JoinColumn(name = "book_id"),
               inverseJoinColumns = @JoinColumn(name = "tag_id"))
    private Set<Tag> tags = new HashSet<>();

    public void setAuthor(Author author) { this.author = author; }
}

Foreign key equals owning side. The other side is just a convenient view.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Hibernate course, and every lesson in it is listed on the Hibernate contents page.