我和学生之间有许多关联。
我的映射
Prepod:
@Entity
@Table(name = "prepod")
public class Prepod {
private Long id;
private String name;
@Column
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
List<Student> students = new ArrayList<Student>();
@ManyToMany(fetch=FetchType.EAGER)
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public Long getId() {
return id;
}
public void setId(Long i) {
id = i;
}[/code]
学生:
@Entity
@Table(name = "Student")
public class Student {
private Long id;
private String name;
private Long age;
private List<Prepod> prepods = new ArrayList<Prepod>();
@ManyToMany(mappedBy = "students",fetch=FetchType.EAGER)
public List<Prepod> getPrepods() {
return prepods;
}
public void setPrepods(List<Prepod> prepods) {
this.prepods = prepods;
}
public Student() {
name = null;
}
public Student(Student s) {
name = s.getName();
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public Long getId() {
return id;
}
@Column(name = "name")
public String getName() {
return name;
}
@Column(name = "age")
public Long getAge() {
return age;
}
public void setId(Long i) {
id = i;
}
public void setName(String s) {
name = s;
}
public void setAge(Long age) {
this.age = age;
}
}
我有两个使用我的模型的变体调用代码。
第一个变种:
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Prepod prepod = (Prepod) session.get(Prepod.class, 1l);
Student student = (Student) session.get(Student.class, 1l);
session.getTransaction().commit();
session.flush();
session.close();
List<Student> students = new ArrayList<Student>();
students.add(student);
List<Prepod> prepods = new ArrayList<Prepod>();
prepods.add(prepod);
prepod.setStudents(students);
student.setPrepods(prepods);
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.update(student);
session.getTransaction().commit();
session.close();
适当的休眠日志:
Hibernate: select prepod0_.id as id1_1_1_, prepod0_.name as name2_1_1_, students1_.prepods_id as prepods1_1_3_, student2_.id as students2_2_3_, student2_.id as id1_0_0_, student2_.age as age2_0_0_, student2_.name as name3_0_0_ from prepod prepod0_ left outer join prepod_Student students1_ on prepod0_.id=students1_.prepods_id left outer join Student student2_ on students1_.students_id=student2_.id where prepod0_.id=?
Hibernate: select student0_.id as id1_0_1_, student0_.age as age2_0_1_, student0_.name as name3_0_1_, prepods1_.students_id as students2_0_3_, prepod2_.id as prepods1_2_3_, prepod2_.id as id1_1_0_, prepod2_.name as name2_1_0_ from Student student0_ left outer join prepod_Student prepods1_ on student0_.id=prepods1_.students_id left outer join prepod prepod2_ on prepods1_.prepods_id=prepod2_.id where student0_.id=?
Hibernate: update Student set age=?, name=? where id=?
此日志显示hibernate仅更新学生实体。与prepod的链接不会更新。
我编写第二个变量代码调用,没有会话关闭:
Prepod prepod = (Prepod) session.get(Prepod.class, 1l);
Student student = (Student) session.get(Student.class, 1l);
session.getTransaction().commit();
session.flush();
// session.close(); // first change
List<Student> students = new ArrayList<Student>();
students.add(student);
List<Prepod> prepods = new ArrayList<Prepod>();
prepods.add(prepod);
prepod.setStudents(students);
student.setPrepods(prepods);
// session = HibernateUtil.getSessionFactory().openSession();//second change
session.beginTransaction();
session.update(student);
session.getTransaction().commit();
session.close();
适当的休眠日志:
Hibernate: select prepod0_.id as id1_1_1_, prepod0_.name as name2_1_1_, students1_.prepods_id as prepods1_1_3_, student2_.id as students2_2_3_, student2_.id as id1_0_0_, student2_.age as age2_0_0_, student2_.name as name3_0_0_ from prepod prepod0_ left outer join prepod_Student students1_ on prepod0_.id=students1_.prepods_id left outer join Student student2_ on students1_.students_id=student2_.id where prepod0_.id=?
Hibernate: select student0_.id as id1_0_1_, student0_.age as age2_0_1_, student0_.name as name3_0_1_, prepods1_.students_id as students2_0_3_, prepod2_.id as prepods1_2_3_, prepod2_.id as id1_1_0_, prepod2_.name as name2_1_0_ from Student student0_ left outer join prepod_Student prepods1_ on student0_.id=prepods1_.students_id left outer join prepod prepod2_ on prepods1_.prepods_id=prepod2_.id where student0_.id=?
Hibernate: insert into prepod_Student (prepods_id, students_id) values (?, ?)
此日志显示在此变体中,这些实体之间的hibernate更新链接。
你能解释一下我的例子之间的主要缺陷吗?
答案 0 :(得分:0)
对处于托管状态的持久性实体所做的更改将变为持久性。这是JPA / Hibernate的全部内容。如果实体处于托管状态(由当前打开的会话加载而未分离),则下次会话刷新时更改将保持不变。如果你没有显式启动事务,那么hibernate将在自动提交模式下执行它。从概念上讲,更新实体与数据库事务边界无关。这些是持久性机制的实现细节,往往会通过抽象泄漏。
答案 1 :(得分:0)
关闭会话时,您的对象变为分离。 阅读本文以获取更多信息http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/objectstate.html