我有3个代码段:
1:
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Prepod prepod = (Prepod) session.load(Prepod.class, 1l);
Student student = (Student) session.load(Student.class, 1l);
Hibernate.initialize(prepod.getStudents());
Hibernate.initialize(student.getPrepods());
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=?
2:从1删除
Hibernate.initialize(prepod.getStudents());
Hibernate.initialize(student.getPrepods());
我们有:
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Prepod prepod = (Prepod) session.load(Prepod.class, 1l);
Student student = (Student) session.load(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();
结果:
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at logic.Prepod_$$_javassist_1.setStudents(Prepod_$$_javassist_1.java)
at logic.Main.main(Main.java:43)
3:更多删除
session.close();
和
session = HibernateUtil.getSessionFactory().openSession();
因此我们有:
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Prepod prepod = (Prepod) session.load(Prepod.class, 1l);
Student student = (Student) session.load(Student.class, 1l);
session.getTransaction().commit();
session.flush();
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.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: insert into prepod_Student (prepods_id, students_id) values (?, ?)
这种行为对我来说不明白。你能解释一下为什么我看到这些结果吗?
更新 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;
}
学生:
@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;
}
}
}
答案 0 :(得分:0)
Hibernate使用自定义proxies
,HibernateProxy
包装延迟加载的集合和对象。其中每个都有一个LazyInitializer
实例来初始化对象(因为它尚未完全加载)。
这些LazyInitializer
个实例扩展了AbstractLazyInitializer
。
方法AbstractLazyInitializer.initialize()
具有以下内容(我们感兴趣)
public final void initialize() throws HibernateException {
if ( !initialized ) {
if ( specjLazyLoad ) {
specialSpecjInitialization();
}
else if ( session == null ) {
throw new LazyInitializationException( "could not initialize proxy - no Session" );
}
...
}
}
在第一个代码段中,您可以调用
Hibernate.initialize(prepod.getStudents());
Hibernate.initialize(student.getPrepods());
关闭Session
之前,初始化Hibernate proxies
,即。 prepod
和student
个对象。因此,他们的initialized
标志设置为true,以后与该对象的所有未来交互都会跳过if
块。
在第二个代码段中,您不会初始化proxies
并关闭Session
。当你试着打电话
prepod.setStudents(students);
它会失败,因为initialized
为false且session
为null
else if ( session == null ) {
throw new LazyInitializationException( "could not initialize proxy - no Session" );
}
在第三个代码段中,您不会关闭Session
所以调用
prepod.setStudents(students);
只会不间断地进行初始化。