Hibernate 冬眠许多作品都像一本书
我想举个例子,看看Hibernate管理的多个关系的表输出。一切似乎都很好。但是,有些行是重复的。我不知道为什么。 我的场景是我有两个简单的类Author&Book。书可以有多个作者,作者可以有多本书 让我们看看类和mysql表输出 Book.javaHibernate 冬眠许多作品都像一本书,hibernate,jpa,Hibernate,Jpa,我想举个例子,看看Hibernate管理的多个关系的表输出。一切似乎都很好。但是,有些行是重复的。我不知道为什么。 我的场景是我有两个简单的类Author&Book。书可以有多个作者,作者可以有多本书 让我们看看类和mysql表输出 Book.java @Entity @Table(name = "BOOK") public class Book { @SequenceGenerator(name = "SEQ_GEN_BOOK", allocation
@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
Mysql表输出如下:(我可以在没有转换表的情况下创建相同的概览)
我希望看到如下表格:
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;
}
我为每个save方法调用创建了不同的会话,并调用了
session.merge()
。我已更改了DbOperations.getInstance().save(..)
方法内容,通过调用session.save()
而不是session.merge()
在同一会话中插入所有给定行。请参阅下面更新的方法,它现在运行良好
public void save(Object... obj) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
try {
for (Object o: obj) {
session.save(o);
}
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();
} finally {
session.close();
}
}
@manytomy
,因此正如hibernate文档所建议的那样,此关联的双方都应该同步。提供用于添加或删除子实体的帮助器方法是一种很好的做法@实体
@表(name=“BOOK”)
公共课堂用书{
@SequenceGenerator(name=“SEQ\u GEN\u BOOK”,allocationSize=1,sequenceName=“TABLE\u SEQ\u GEN\u BOOK”,initialValue=1)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“SEQ\u GEN\u BOOK”)
@身份证
@列(name=“ID”)
私人长id;
@列(name=“name”,null=false,长度=100)
私有字符串名称;
//不要使用原始类型
//例如,请参见此示例https://stackoverflow.com/questions/2770321
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
私人电视台
所以,你应该这样做:
author1=新作者();
author1.setName(“author1”);
Author author2=新作者();
author2.setName(“author2”);
Author author3=新作者();
author3.setName(“author3”);
Book book1=新书();
账簿1.集合名称(“账簿1”);
Book book2=新书();
账簿2.设置名称(“账簿2”);
Book book3=新书();
book3.设置名称(“book3”);
Book book4=新书();
账簿4.设置名称(“账簿4”);
book1.添加作者(author1);
书1.添加作者(author2);
第2册。添加作者(author1);
第2册。添加作者(author2);
第2册。添加作者(author3);
第3册。添加作者(author2);
第三册。添加作者(author3);
第4册。添加作者(author3);
Session Session=HibernateUtil.getSessionFactory().openSession();
事务=会话。beginTransaction();
session.persist(第1册);
session.persist(第2册);
session.persist(第3册);
session.persist(第4册);
commit();
session.close();
DbOperations.getInstance().save()
do是什么?如果它在每次调用时创建一个新的实体管理器(即持久性上下文),那么这意味着每次它保存实体的新版本时,您甚至可以调用DbOperations.getInstance().save(book1)
多次,希望在Book Table中看到Book1的多个条目。它创建了一个新会话,然后调用merge方法。请参见上文(我已添加)中的内容。如果我调用merge方法而不是persist/save,则结果不会更改。save&persist解决了在同一会话中调用它们时的问题。谢谢@SternK
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;
}
public void save(Object... obj) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
try {
for (Object o: obj) {
session.save(o);
}
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();
} finally {
session.close();
}
}