I' m tring to make an example to see table output of ManyToMany relationship managed by Hibernate. Everthing seems well. However, some rows are duplicated. I do not know why. My Scenario is that I have 2 simple Classes Author & Book. Book can have more than one author and Author can have more than one book.
Let' s see classes and mysql table output.
Book.java
@Entity
@Table(name = "BOOK")
public class Book {
@SequenceGenerator(name = "SEQ_GEN_BOOK", allocationSize = 1, sequenceName = "TABLE_SEQ_GEN_BOOK", initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN_BOOK")
@Id
@Column(name = "ID")
private long id;
@Column(name = "NAME", nullable = false, length = 100)
private String name;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = Author.class)
private Set authors = new HashSet();
//setter/getters
Author.java
@Entity
@Table(name = "Author")
public class Author {
@SequenceGenerator(name = "SEQ_GEN_AUTHOR", initialValue = 1, sequenceName = "TABLE_SEQ_GEN_AUTHOR", allocationSize = 1)
@GeneratedValue(generator = "SEQ_GEN_AUTHOR", strategy = GenerationType.SEQUENCE)
@Id
@Column(name = "ID")
private long id;
@Column(name = "NAME", nullable = false, length = 100)
private String name;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "authors")
private Set<Book> books = new HashSet<Book>();
//setter/getters
main method is
public static void main(String[] args) throws InterruptedException {
Author author1 = new Author();
author1.setName("author1");
Author author2 = new Author();
author2.setName("author2");
Author author3 = new Author();
author3.setName("author3");
Book book1 = new Book();
book1.setName("book1");
Book book2 = new Book();
book2.setName("book2");
Book book3 = new Book();
book3.setName("book3");
Book book4 = new Book();
book4.setName("book4");
book1.getAuthors().add(author1);
book1.getAuthors().add(author2);
book2.getAuthors().add(author1);
book2.getAuthors().add(author2);
book2.getAuthors().add(author3);
book3.getAuthors().add(author2);
book3.getAuthors().add(author3);
book4.getAuthors().add(author3);
DbOperations.getInstance().save(book1);
DbOperations.getInstance().save(book2);
DbOperations.getInstance().save(book3);
DbOperations.getInstance().save(book4);
}
Mysql Table output is below: (i can create the same overview without having transition table)
mysql> show tables;
+------------------------+
| Tables_in_hibernatedb1 |
+------------------------+
| author |
| book |
| book_author |
| table_seq_gen_author |
| table_seq_gen_book |
+------------------------+
5 rows in set (0.00 sec)
mysql> select * from book_author;
+----------+------------+
| books_ID | authors_ID |
+----------+------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
| 2 | 5 |
| 3 | 6 |
| 3 | 7 |
| 4 | 8 |
+----------+------------+
8 rows in set (0.00 sec)
mysql> select * from book;
+----+-------+
| ID | NAME |
+----+-------+
| 1 | book1 |
| 2 | book2 |
| 3 | book3 |
| 4 | book4 |
+----+-------+
4 rows in set (0.00 sec)
mysql> select * from author;
+----+---------+
| ID | NAME |
+----+---------+
| 1 | author1 |
| 2 | author2 |
| 3 | author1 |
| 4 | author2 |
| 5 | author3 |
| 6 | author2 |
| 7 | author3 |
| 8 | author3 |
+----+---------+
8 rows in set (0.00 sec)
My Expectation is to see tables like below:
mysql> select * from book_author;
+----------+------------+
| books_ID | authors_ID |
+----------+------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 2 |
| 3 | 3 |
| 4 | 3 |
+----------+------------+
mysql> select * from book;
+----+-------+
| ID | NAME |
+----+-------+
| 1 | book1 |
| 2 | book2 |
| 3 | book3 |
| 4 | book4 |
+----+-------+
mysql> select * from author;
+----+---------+
| ID | NAME |
+----+---------+
| 1 | author1 |
| 2 | author2 |
| 3 | author3 |
+----+---------+
DBOperation.class
public Object save(Object o) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
Object merge = null;
try {
merge = session.merge(o);
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();
} finally {
session.close();
}
return merge;
}