In a many-to-one relationship, many instances of one entity can be associated with a single instance of another entity. This is the opposite of a one-to-many relationship, where a single instance of one entity is associated with many instances of another entity. Here's an example of how to implement a unidirectional many-to-one mapping in Hibernate using annotations:
Assume we have two entities, Book and Author. Each book can have only one author, but each author can have many books. Here's how the Book entity can be mapped:
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
private Author author;
// getters and setters
}
In this example, the Book entity has a @ManyToOne annotation on the author field. This indicates that each book has exactly one author, and the fetch = FetchType.LAZY attribute specifies that the author should be fetched lazily. The @JoinColumn annotation is used to specify the foreign key column in the book table that references the author table.
Here's how the Author entity can be mapped:
@Entity
@Table(name = "author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// getters and setters
}
In this example, the Author entity doesn't have any mapping for the Book entity, as this is a unidirectional mapping.
In a bidirectional many-to-one relationship, an instance of one entity can be associated with many instances of another entity, and each instance of the other entity can be associated with exactly one instance of the first entity. Here's an example of how to implement a bidirectional many-to-one mapping in Hibernate using annotations:
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
private Author author;
// getters and setters
}
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
private Author author;
// getters and setters
}
In this example, the Book entity has the same mapping as before.
Here's how the Author entity can be mapped for a bidirectional many-to-one relationship:
@Entity
@Table(name = "author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Book> books = new ArrayList<>();
// getters and setters
}
In this example, the Author entity has a @OneToMany annotation on the books field, which indicates that an author can have many books. The mappedBy = "author" attribute specifies that the Book entity's author field is used to map to the Author entity. The cascade = CascadeType.ALL attribute specifies that any changes made to an Author instance should be propagated to all associated Book instances, and the orphanRemoval = true attribute specifies that any Book instances that are no longer associated with an Author instance should be removed from the database.
With this bidirectional mapping, we can now access the author of a book as well as the books of an author. Here's an example:
Author author = new Author();
author.setName("J.K. Rowling");
Book book1 = new Book();
book1.setTitle("Harry Potter and the Philosopher's Stone");
book1.setAuthor(author);
Book book2 = new Book();
book2.setTitle("Harry Potter and the Chamber of Secrets");
book2.setAuthor(author);
author.getBooks().add(book1);
author.getBooks().add(book2);
session.save(author);
In this example, we create a new Author instance and set its name to "J.K. Rowling". We also create two new Book instances and set their titles, as well as the author of each book. Finally, we add both Book instances to the author's books list and save the author to the database using the Hibernate Session object. With this bidirectional mapping, we can easily access all of an author's books by calling author.getBooks().
Assume we have the same Book and Author entities as before. Here's how the Book entity can be mapped: