не удалось лениво инициализировать коллекцию ролей: com.pojo.Student.phonenos, ни один сеанс или сеанс не был закрыт - PullRequest
6 голосов
/ 20 октября 2011

Я изучаю отображение спящего режима с помощью аннотации. Я закончил один раздел. То есть Я могу вставить дочерний класс автоматически при сохранении родительской таблицы. see_that .

Но я не получил дочернюю таблицу, когда выбираю главную таблицу. Также получаю ошибку

failed to lazily initialize a collection of role: com.pojo.one2many.unidirectional.Student.phonenos, no session or session was closed

Мой код добавлен здесь для просмотра вас. Пожалуйста, пройдите. И дай мне отличный совет. Student.java. (родительский класс)

@Entity
    @Table(name="STUDENT")
    public class Student {
    private int studentid;
    private String studentName;
    private Set <Phone> phonenos;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="studenId")
    public int getStudentid() {
        return studentid;
    }
    public void setStudentid(int studentid) {
        this.studentid = studentid;
    }
    @Column(name="studenName")
    public String getStudentName() {
        return studentName;
    }
    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name="studenId") 
    public Set<Phone> getPhonenos() {
        return phonenos;
    }
    public void setPhonenos(Set<Phone> phonenos) {
        this.phonenos = phonenos;
    }

Phone.java (дочерний класс)

@Entity
@Table(name = "PHONE")
public class Phone {
    private int phoneid;
    private String phoneNo;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "phoneId")
    public int getPhoneid() {
        return phoneid;
    }
    public void setPhoneid(int phoneid) {
        this.phoneid = phoneid;
    }
    @Column(name = "phoneno")
    public String getPhoneNo() {
        return phoneNo;
    }
    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }

мой дао класс

public List<Student> getAllStudent() {
         List<Student> studentList = null;
         try {
            DetachedCriteria criteria = DetachedCriteria.forClass(Student.class);
             studentList = (List<Student>)getHibernateTemplate().findByCriteria(criteria);
              if(studentList != null && ! studentList.isEmpty()){
                 for(Student st :studentList){
                     System.out.println(" st name : "+st.getStudentName());
                     if(st.getPhonenos() != null && ! st.getPhonenos().isEmpty()){
                         for(Phone ph : st.getPhonenos()){
                             System.out.println(" ph no : "+ ph.getPhoneNo());
                         }
                     }else{
                         System.out.println("   phone number is null");
                     }
                 }
             }else{
                 System.out.println("   student null");
             }
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        return studentList;
    }

Выход -

failed to lazily initialize a collection of role: com.pojo.one2many.unidirectional.Student.phonenos, no session or session was closed

Здесь я использую однонаправленное (внешний ключ) отображение «один ко многим» (не объединенная таблица, двунаправленное).

Подводя итог моему вопросу

1) как получить дочернюю таблицу, когда мы выбираем родительскую таблицу, и наоборот

2) что за нетерпение и ленивость.

3) таблица однонаправленности, двунаправленности и соединения в случае сопоставления «один ко многим», который более полон.

1 Ответ

5 голосов
/ 20 октября 2011

1)

Если вы действительно хотите делать это каждый раз, когда извлекается какая-либо сущность этих классов, укажите FetchMode.EAGER в ассоциации @OneToMany.@ManyToOne хотят по умолчанию.Имейте в виду, что это может быть в значительной степени неэффективно, если вам нужно получить эти объекты только в определенных обстоятельствах.Если это так, вы должны сделать это так, как делаете, но убедитесь, что сеанс, который получил объект Student, все еще открыт.Видя, что вы используете Spring, пытались ли вы аннотировать DAO / Service с помощью @Transactional, чтобы сеанс сохранялся во время выполнения метода?Или вы пытались использовать Hibernate.execute(), например:

   getHibernateTemplate().execute(new HibernateCallback(){
    @SuppressWarnings("unchecked")
    public Object doInHibernate(Session s) throws HibernateException, SQLException {
        Criteria c = s.createCriteria(Student.class);
        List<Student> studentList = c.list();
        for(Student st :studentList){
            st.getPhoneNos();
        }
    }
});

2) Взгляните на этот вопрос: Разница между FetchType LAZY и EAGER в персистентности Java? .

3) Это зависит от того, что вам нужно.Если вам нужно перемещаться по ассоциации только одним способом, определите ее только однонаправленным образом.Если вам нужны оба, сделайте оба.Join Table больше связан с дизайном базы данных.Если вы хотите иметь FK в таблице Phone со ссылкой на Student, к которому принадлежит телефон, или вы хотите иметь таблицу соединения с Phones каждого Student.

...