JPA Many-to-Many Relationship
In this section, you will learn about the many-to-many relationship and how to develop a many-to-many relation in your JPA Application.
Many-to-many: In this relationship each record in Table-A may have many related records in Table-B and vice-versa.
We are going to describe many-to-many relation. If you want to create any relation then you need more than one table. There are three tables: author, autor_book and book. Many authors write a book and many books are written by a author. So, we can say that there is many-to-many relation between author and book table. Both tables are connected by author_book table.
[Note: If in the database hasn't required table and you run this application then it will automatically create in your database according to your given model class. Otherwise, it only insert the value in your database table.]
You see the following image that represents many-to-one relationship:
To develop the JPA Many-to-Many relation, you need the following files:
Database Table:- author
- book
- author_book
<?xml version="1.0" encoding="UTF-8"?> <persistence> <persistence-unit name="default"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>roseindia.Person</class> <class>roseindia.Address</class> <class>roseindia.Parent</class> <class>roseindia.Child</class> <class>roseindia.Author</class> <class>roseindia.Book</class> <properties> <property name="hibernate.connection.url" value="jdbc:mysql://192.168.10.146:3306/hibernateannotation"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.password" value="root"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <!-- Echo all executed SQL to stdout --> <property name="hibernate.show_sql" value="true"/> </properties> </persistence-unit> </persistence>Model Class:
- Author.java
- Book.java
- ManyToManyRelation.java
- author
CREATE TABLE `author` (
`id` int(11) NOT NULL auto_increment,
`authorName` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) - book
CREATE TABLE `book` (
`id` int(11) NOT NULL auto_increment,
`bookName` varchar(250) NOT NULL,
PRIMARY KEY (`id`)
) - author_book
CREATE TABLE `author_book` (
`bookId` int(11) NOT NULL,
`authorId` int(11) NOT NULL,
PRIMARY KEY (`authorId`,`bookId`),
KEY `FK2A7A111DB63F85B3` (`bookId`),
KEY `FK2A7A111DFC08F7` (`authorId`),
CONSTRAINT `FK2A7A111DB63F85B3` FOREIGN KEY (`bookId`) REFERENCES `book` (`id`),
CONSTRAINT `FK2A7A111DFC08F7` FOREIGN KEY (`authorId`) REFERENCES `author` (`id`)
)
- Author.java
/**
*
*/
package roseindia;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
/**
* @author Administrator
*
*/
@Entity
@Table(name="author")
public class Author {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
private int id;
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
@Column(name="authorName", nullable=false, length=50, insertable=true)
private String authorName;
/**
* @return the authorName
*/
public String getAuthorName() {
return authorName;
}
/**
* @param authorName the authorName to set
*/
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
//for joing the tables (many-to-many)
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "author_book",
joinColumns = {
@JoinColumn(name="authorId")
},
inverseJoinColumns = {
@JoinColumn(name="bookId")
}
)
private Set<Book> books;
/**
* @return the books
*/
public Set<Book> getBooks() {
return books;
}
/**
* @param books the books to set
*/
public void setBooks(Set<Book> books) {
this.books = books;
}
}
- Book.java
/**
*
*/
package roseindia;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
/**
* @author Administrator
*
*/
@Entity
@Table(name="book")
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
private int id;
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
@Column(name="bookName", nullable=false, length=250, insertable=true)
private String bookName;
/**
* @return the bookName
*/
public String getBookName() {
return bookName;
}
/**
* @param bookName the bookName to set
*/
public void setBookName(String bookName) {
this.bookName = bookName;
}
//for joing the tables (many-to-many)
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "author_book",
joinColumns = {
@JoinColumn(name="bookId")
},
inverseJoinColumns = {
@JoinColumn(name="authorId")
}
)
private Set<Author> authors;
/**
* @return the authors
*/
public Set<Author> getAuthors() {
return authors;
}
/**
* @param authors the authors to set
*/
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
}
- ManyToManyRelation.java
/**
*
*/
package roseindia;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
* @author Administrator
*
*/
public class ManyToManyRelation {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
EntityManagerFactory emf=null;
EntityManager em=null;
try{
emf=Persistence.createEntityManagerFactory("default", new HashMap());
em=emf.createEntityManager();
em.getTransaction().begin();
Author author = new Author();
author.setAuthorName("Clifford Geertz");
Author author1 = new Author();
author1.setAuthorName("JP Morgenthal");
HashSet authorSet = new HashSet();
authorSet.add(author);
authorSet.add(author1);
Book book = new Book();
book.setBookName("Phoenix");
Book book1 = new Book();
book1.setBookName("Enterprise Applications Integration with XML and Java");
book.setAuthors(authorSet);
book1.setAuthors(authorSet);
em.persist(book);
em.persist(book1);
Book bookRecord = em.find(Book.class, book.getId());
System.out.println("Book: "+ bookRecord.getBookName());
Set<Author> authset = bookRecord.getAuthors();
Iterator it = authset.iterator();
while(it.hasNext()){
Author a = (Author)it.next();
System.out.println("Author: "+ a.getAuthorName());
}
em.getTransaction().commit();
System.out.println("Done");
}
catch(Exception e){
System.out.println(e.getMessage());
}
finally{
em.close();
emf.close();
}
}
}
log4j:WARN No appenders could be found for logger
(org.hibernate.cfg.annotations.Version).log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into book (bookName) values (?)
Hibernate: insert into author (authorName) values (?)
Hibernate: insert into author (authorName) values (?)
Hibernate: insert into book (bookName) values (?)
Book: Phoenix
Author: Clifford Geertz
Author: JP Morgenthal
Hibernate: insert into author_book (bookId, authorId) values (?, ?)
Hibernate: insert into author_book (bookId, authorId) values (?, ?)
Hibernate: insert into author_book (bookId, authorId) values (?, ?)
Hibernate: insert into author_book (bookId, authorId) values (?, ?)
Done
Table author:
Table book:
Table author_book: