Java 休眠行为说明:

Java 休眠行为说明:,java,hibernate,jpa,orm,Java,Hibernate,Jpa,Orm,我有3个代码片段: 1: 2:从1中删除 Hibernate.initialize(prepod.getStudents()); Hibernate.initialize(student.getPrepods()); 我们有: Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); Prepod prep

我有3个代码片段:

1:

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();
3:更多删除

session.close();

因此,我们:

    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: insert into prepod_Student (prepods_id, students_id) values (?, ?)
我不理解这种行为。你能解释我为什么看到这些结果吗

更新 前置词:

@实体
@表(name=“prepd”)
公共类介词{
私人长id;
私有字符串名称;
@纵队
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
List students=new ArrayList();
@ManyToMany(fetch=FetchType.EAGER)
公众学生名单{
留学生;
}
公立学校学生(名单学生){
这个。学生=学生;
}
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“id”)
公共长getId(){
返回id;
}
公共无效设置ID(长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;
    }
}
}
@实体
@表(name=“Student”)
公立班学生{
私人长id;
私有字符串名称;
私人长寿;
private List preposd=new ArrayList();
@ManyToMany(mappedBy=“students”,fetch=FetchType.EAGER)
公共列表getPrepDS(){
返回介词;
}
公共void setprepDS(列表prepDS){
this.preposds=preposds;
}
公立学生(){
name=null;
}
公立学生{
name=s.getName();
}
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“id”)
公共长getId(){
返回id;
}
@列(name=“name”)
公共字符串getName(){
返回名称;
}
@列(name=“age”)
公共长假{
回归年龄;
}
公共无效设置ID(长i){
id=i;
}
公共void集合名(字符串s){
name=s;
}
公共空间设置(长时间){
这个。年龄=年龄;
}
}
}

Hibernate使用其自定义的
代理
HibernateProxy
包装延迟加载的集合和对象。每一个都有一个
LazyInitializer
实例来初始化对象(因为它还没有完全加载)

这些
LazyInitializer
实例扩展了
AbstractLazyInitializer

方法
AbstractLazyInitializer.initialize()
具有以下内容(我们感兴趣)

第一个片段中,调用

Hibernate.initialize(prepod.getStudents());
Hibernate.initialize(student.getPrepods());
在关闭初始化Hibernate
代理(即
prepod
student
对象)的
会话之前。因此,它们的
initialized
标志被设置为true,并且将来与对象的所有交互都跳过
if

在第二个代码段中,您不会初始化
代理
并关闭
会话
。当你试着打电话的时候

prepod.setStudents(students);
它将失败,因为
initialized
为false,而
会话
null

else if ( session == null ) {
    throw new LazyInitializationException( "could not initialize proxy - no Session" );
}
第三个代码段中,您没有关闭
会话
,因此

prepod.setStudents(students);

将不间断地执行初始化

在所有示例中,我都使用了渴望初始化。我认为它加载了关系集合。@user2674303继续并发布您的实体映射。@User您比我更适合检查,但Hibernate仍然会代理您的类,即使您已经加载了关系集合。@user2674303使用调试器。您会注意到
prepd
引用的类类型实际上是
prepd\u$$\ uJavassist\u1
类型的代理。
@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;
    }
}
}
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());
prepod.setStudents(students);
else if ( session == null ) {
    throw new LazyInitializationException( "could not initialize proxy - no Session" );
}
prepod.setStudents(students);