From the course: Java Persistence with JPA and Hibernate

@OneToMany and @ManyToOne annotations in a relationship - JPA Tutorial

From the course: Java Persistence with JPA and Hibernate

@OneToMany and @ManyToOne annotations in a relationship

- [Instructor] A one to many relationship means one of something is linked with many of another thing. For example, a book can have many reviews. This is a type of relationship where one instance of an entity is linked with multiple instances of another entity. Let's run the MariaDB 06_02 SQL script first. In the library database, there's the book table and the review table. Book_id is the primary key of the book table. And in the review table, there's the book_id as a foreign key. How do we map this in hibernate? There are two annotations that are used, the @OneToMany and @ManyToOne annotations. Like one to one relationships, one to many relationships also can come in both unidirectional and bidirectional forms. That is, the relationship can be from the book side or the review side. These two annotations are used on the two different sides of the same relationship. Let's say that a book may have several reviews, but a given review belongs to only one book. So from the book side, there's a one to many relationship with the review entity. In other words, the book entity defines a one to many relationship with the review entity. The book entity is defined already, and I've defined the review entity also here for you. To map the relationship that we saw just now, in the book class, define a field named reviews. Let's go to the book class and let's define a field named reviews. Private List Review and reviews. It should be a collection type like a list because one instance of the book entity could be linked with multiple instances of the review entity. The list will of course contain review objects. Generate getters and setters for it as well. Right here. Let's generate getters and setters. Then annotate the field with @OneToMany annotation. @OneToMany. Now if you think of the same relationship from the review side, there's a many to one relationship with the book entity. In other words, the review entity defines a many to one relationship with the book entity. This is said to be the owner of the relationship because it contains the foreign key. To map this side of the relationship in the review class, define a field named book of type book. So right here, let's define private Book and call it book and define a getter and setter for it. Right click source action and generate getters and setters. When you do this, the review has a reference to the single book to which it belongs. Now annotate it with the @ManyToOne annotation. @ManyToOne. Additionally, use the @JoinColumn annotation on it to specify the name of the column in the review table that maps to the primary key of the book table, or in other words, the foreign key of the review table, that is, book_id. So let's also add @JoinColumn annotation with its name attribute set to book_id. The @JoinColumn annotation is always used on the owner side of the relationship to specify the foreign key column. Back in the book entity class, to complete the relationship, you should use the mappedBy attribute in the @OneToMany annotation. So let's type the mappedBy attribute and set it to book. The mappedBy attribute is used to mark the inverse side of a relationship. Using this attribute, you specify the name of the field on the opposite side entity to which this field will be mapped. For example, in this case it is book. In addition, set the cascade attribute to CascadeType.ALL. Let's also type cascade attribute and set it to CascadeType.ALL. In relationships between entities, cascading is the mechanism to propagate whatever the operations that you do to the target entity to the associated entity or entities as well. Cascade attribute can be used on the @OneToOne annotation as well. But in this case, it's specifically useful because we want to save the review entity instances whenever the target entity instance, which is book, gets saved. CascadeType.ALL propagates all operations like persist, merge, remove, refresh, and detach to all the associated entities. To check this out in the main class in one to many relationship method, I've added code to persist a new book instance and an author set to the book. Then create two review instances. Make sure you import the review class. Set comments to them and set each of them to the book. Remember to also set the reviews as a list to the book because this is what establishes the one to many relationship between them. And then persist the book. That's it. Now run the program. If everything went well, you should get three insert statements, one for the book and the other two for the two reviews that we entered. In the database, the book should be inserted in the book table. Then in the review table, there are the two reviews that you entered. The correct book ID is reflected in the review records. And that's how you use the @OneToMany and @ManyToOne annotations to map a one to many relationship.

Contents