2013-09-12 5 views
0

У меня есть 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 (?, ?) 

Такое поведение не понимает меня. Можете ли вы объяснить мне, почему я увидел эти результаты?

UPDATE 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

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 ложно и session является null

else if (session == null) { 
    throw new LazyInitializationException("could not initialize proxy - no Session"); 
} 

В вашем третьем сниппета, вы не закрыть Session поэтому вызов

prepod.setStudents(students); 

будет выполнять инициализацию без перерыва.

+0

Во всех примерах я использую инициализацию EAGER. Я думаю, что он загружает коллекцию отношений. – gstackoverflow

+0

@ user2674303 Перейдите и разместите сопоставления объектов. –

+0

добавлено в тему – gstackoverflow

 Смежные вопросы

  • Нет связанных вопросов^_^