Hibernate One To Many Association Example

By | | Updated : 2021-01-10 | Viewed : 723 times

Hibernate One To Many Association Example

The current post describes the OneToMany Association in Hibernate. Here we are going to learn the OneToMany Association and its example.

One To Many Association

So, first of all, we need to know What is OneToMany Association? To know about this mapping consider the example of the Association between Author and book. We can define the relationship as one author can write many books. So, the Author table row can be mapped with multiple rows of books table.

Required Dependencies

The required jars for the current project are provided given below.

Maven Dependencies for OneToMany Association
	<!-- Hibernate 5.4.3.Final -->
	 <dependency>
		 <groupId>org.hibernate</groupId>
	 	<artifactId>hibernate-core</artifactId>
	 	<version>${hibernate-core-version}</version>
	 </dependency>
	 
	 <!-- MySql Driver -->
	 <dependency>
		 <groupId>mysql</groupId>
		 <artifactId>mysql-connector-java</artifactId>
	 	<version>${mysql.connector.version}</version>
	 </dependency>

Please Observe that we are using the dependencies hibernate-core and mysql-connector-java. hibernate-core is the main jar for the Hibernate applications.

one to many association with Foreign Key

We can configure the metadata in two ways those are annotations and XML. We will see both examples for the configuration of OneToMany association.

Database Setup

The first step is defining the database tables for OneToMany Association example.

Create table for Author
CREATE TABLE `author` (
    `AUTHOR_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `AUTHOR_NAME` VARCHAR(50) NOT NULL,
     PRIMARY KEY (`AUTHOR_ID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=13;
Create table for Book

CREATE TABLE `book` (
    `BOOK_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `AUTHOR_ID` INT(10) UNSIGNED NOT NULL,
    `BOOK_NAME` VARCHAR(50) NOT NULL,
    `BOOK_PRICE` DOUBLE NOT NULL,
    PRIMARY KEY (`BOOK_ID`),
    INDEX `AUTHOR_ID` (`AUTHOR_ID`),
    CONSTRAINT `BOOKS_FK` FOREIGN KEY (`AUTHOR_ID`) REFERENCES  `author` (`author_id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=34;

Here we will use the foreign key constraint based relationship for this association. Here book table will have a foreign key constraint. This key referer the primary key of the author's table.

Our first step which is database setup is ready. Let's move on to the next step which is creating the project for executing the example.

Annotation Example

Entity Class for Author
	@Entity
	@Table(name = "AUTHOR")
	public class Author {
	 
		@Id
		@GeneratedValue(strategy = GenerationType.IDENTITY)
		@Column(name = "AUTHOR_ID")
		private long prodDetailsId;
	 
		@Column(name = "AUTHOR_NAME")
		private String authorName;
	 
		@OneToMany(mappedBy = "bookId")
		private Set<Book> Books;
	 	//setters and getters	 
	}

Here we are mapping one author entity with multiple book entities. We used the same @OneToMany(mappedBy = "bookId"). Here mappedBy attribute is used for the bidirectional association.

Entity Class for Book
	@Entity
	@Table(name = "BOOK")
	public class Book {
	 
		@Id
		@GeneratedValue(strategy = GenerationType.IDENTITY)
		@Column(name = "BOOK_ID")
		private Long bookId;
	 
		@Column(name = "BOOK_NAME")
		private String bookName;
	 
		@Column(name = "BOOK_PRICE")
		private Double bookPrice;
	 
		@ManyToOne
		@JoinColumn(name = "AUTHOR_ID", nullable = false)
		private Author author;
	 	//setters and getters
	 }

We mapped here many books with one author. We used @ManyToOne for the same. @JoinColumn is for representing the foreign key column of Book.

XML Example

To represent the One To Many association with XML configurations then you can refer below for the same.

author.hbm.xml
	<class name="Author" table="AUTHOR">

		<id name="authorId" column="AUTHOR_ID">
			<generator class="identity" />
		</id>
		<property name="authorName" column="AUTHOR_NAME"></property>
		<set name="books" table="books" inverse="true" lazy="true" fetch="select">
			<key>
				<column name="bookId" not-null="true" />
			</key>
			<one-to-many class="com.docsconsole.tutorials.hibernate5.entity.Book" />
		</set>

	</class>

To map one with the author with many books we need to used set tag as shown above. Here inverse is for making the relationship bidirectional. In the set tag, one-to-many tag should be used for the book.

book.hbm.xml
	<class name="Book" table="book">
	
		<id name="bookId" column="BOOK_ID">
			<generator class="identity" />
		</id>
		<property name="bookName" column="BOOK_NAME"></property>
		<property name="bookPrice" column="BOOK_PRICE"></property>
		<many-to-one name="author" class="com.docsconsole.tutorials.hibernate5.entity.Author" fetch="select">
           		 	<column name="AUTHOR_ID" not-null="true" />
       		 </many-to-one>
	</class>

Here we need to use the many-to-one tag for mapping many books with one author.

Saving The Entities

Need to created author and book entity objects as given below.

Create author and book entity objects
	 Author author1 = new Author();
	 author1.setAuthorName("Author1");
	 
	 Book book1 = new Book("Book1", 100.0, author1);
	 Book book2 = new Book("Book2", 200.0, author1);
	 Book book3 = new Book("Book3", 300.0, author1);

Prepare the hash object and set it to the author as given below.

Create Set object and set it to the author
	 Set<Book> books = new HashSet<Book>();
	 books.add(book1);
	 books.add(book2);
	 books.add(book3);
	 
	 author1.setBooks(books);

Save the objects as given below by using the session.

Save the objects
	 session.save(author1);
	 session.save(book1);
	 session.save(book2);
	 session.save(book3);

To check code base please look Hibernate-ManyToOne-Association-Annotation-Example.

One To Many Association With Join Table

here we will look into the same Hibernate One To Many Association with Join Table. For that first, we will set up the database how it should be.

Database setup for One To Many Association with Join Table
CREATE TABLE `author_1` (
  	`AUTHOR_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  	`AUTHOR_NAME` VARCHAR(50) NOT NULL,
  	PRIMARY KEY (`AUTHOR_ID`)
  );

CREATE TABLE `book_1` (
	`BOOK_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`BOOK_NAME` VARCHAR(50) NOT NULL,
	`BOOK_PRICE` DOUBLE NOT NULL,
	PRIMARY KEY (`BOOK_ID`)
);
CREATE TABLE `author_book_1` (
	`AUTHOR_BOOK_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`AUTHOR_ID` INT(10) UNSIGNED NOT NULL,
	`BOOK_ID` INT(10) UNSIGNED NOT NULL,
	PRIMARY KEY (`AUTHOR_BOOK_ID`),
	INDEX `AUTHOR_ID` (`AUTHOR_ID`),
	INDEX `BOOK_ID` (`BOOK_ID`),
	CONSTRAINT `AUTHOR_FK` FOREIGN KEY (`AUTHOR_ID`) REFERENCES `author_1` (`author_id`),
	CONSTRAINT `BOOK_FK` FOREIGN KEY (`BOOK_ID`) REFERENCES `book_1` (`book_id`)
);

Annotation Example

Author.java
@Entity
@Table(name = "AUTHOR_1")
@Getter
@Setter
@AllArgsConstructor
public class Author {
	//required properties
	@OneToMany(cascade= CascadeType.ALL)
	@JoinTable(name="author_book_1", joinColumns={@JoinColumn(name="AUTHOR_ID", referencedColumnName="AUTHOR_ID")}
			, inverseJoinColumns={@JoinColumn(name="BOOK_ID", referencedColumnName="BOOK_ID")})
	private Set<Book> Books;
}
Book.java
@Entity
@Table(name = "BOOK_1")
@Getter
@Setter

public class Book {
	//add all properties
}

Notice we used set collections with @OneToMany, @JoinTable annotations in the Author entity class.

@OneToMany annotation indicates that one to many relations between Author and Books entities.

The @JoinTable is mainly used in both bidirectional as well as unidirectional associations i.e., bidirectional of many-to-one/one-to-many and unidirectional of many-to-one/one-to-one associations. It is commonly used in the owning side of the association i.e., relationship owne. In our case, the Author is the owner of the relationship.

Here we have two attributes one is joinColumns and the other one is inverseJoinColumns. Here joinColumns is used to mapping the forienkey relationship with the owner of the relationship that is in our case Author. With other property inverseJoinColumns, the forienkey relationship has declated with nonowner of the relationship in our case Book.

XML Example

author.hbm.xml
<hibernate-mapping package="com.docsconsole.tutorials.hibernate5.entity" default-access="property">

	<class name="Author" table="author_1">

		<id name="authorId" column="AUTHOR_ID">
			<generator class="identity" />
		</id>
		<property name="authorName" column="AUTHOR_NAME"></property>

		<set name="Books" table="author_book_1" cascade="all">
			<key column="AUTHOR_ID" not-null="true" />
			<many-to-many column="BOOK_ID" class="Book" unique="true"/>
		</set>

	</class>
book.hbm.xml
<class name="Book" table="book_1">
	
		<id name="bookId" column="BOOK_ID">
			<generator class="identity" />
		</id>
		<property name="bookName" column="BOOK_NAME"></property>
		<property name="bookPrice" column="BOOK_PRICE"></property>

	</class>

This is also working as the above annotation example. Here we used set tag with manay-to-many tag.

key tag is used to map the table by foreign key relationship.

many-to-many is used for mapping many to many relationships. As we used property unique = true so it makes relationship as

GitHub repository for JoinTable XML is Hibernate-OnetoMany-Association-JoinTable-XML-Example-App

GitHub repository for JoinTable Annotation is Hibernate-OnetoMany-Association-JoinTable-Annotation-Example-App

Leave A Reply