no pudo inicializar perezosamente una colección de roles: com.pojo.Student.phonenos, no se cerró ninguna sesión o sesión

StackOverflow https://stackoverflow.com/questions/7832433

Pregunta

Estoy aprendiendo a hacer mapas de hibernación mediante anotaciones. He completado una sección. Es decir. Puedo insertar una clase secundaria automáticamente cuando guardo la tabla principal. ver_esto .

Pero no obtuve la tabla secundaria cuando busqué la tabla maestra. También aparece un error

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

Mi código se agrega aquí para revisarlo. Por favor revíselo. Y dame un gran consejo. Student.java. (clase principal)

@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 (clase secundaria)

@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;
    }

mi clase de dao

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;
    }

Lo que queda es

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

Aquí estoy usando un mapeo unidireccional (clave externa) uno a varios (no una tabla conjunta, bidireccional).

Mejorando mi pregunta

1) cómo obtener la tabla secundaria cuando buscamos la tabla principal, viceversa

2) lo que se busca ansioso y perezoso.

3) tabla de unidirección, bidirección y combinación en el caso de la asignación de uno a varios, cuál es más potente.

¿Fue útil?

Solución

1)

Si realmente desea hacer esto cada vez que se recupera cualquier entidad de estas clases, especifique FetchMode.EAGER en la asociación @OneToMany. @ManyToOne están ansiosos por defecto. Tenga en cuenta que esto puede resultar muy poco eficaz si necesita recuperar esas entidades solo en circunstancias particulares. Si ese es el caso, debe hacerlo como lo está haciendo, pero asegúrese de que la sesión que recuperó el objeto Student todavía esté abierta. Al ver que está utilizando Spring, ¿ha intentado anotar su DAO / Servicio con @Transactional, para que la sesión se mantenga viva durante la ejecución del método? ¿O ha intentado utilizar Hibernate.execute(), como este:

   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) Eche un vistazo a esta pregunta: ¿Diferencia entre FetchType LAZY y EAGER en la persistencia de Java? .

3) Depende de lo que necesite. Si solo necesita navegar por la asociación de una manera, defínela unidireccional solo de esa manera. Si necesita ambos, haga ambos. Join Table tiene más que ver con el diseño de bases de datos. Si desea tener un FK en la tabla Phone con la referencia al Student al que pertenece el teléfono, o desea tener una tabla de combinación con el Phones de cada Student.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top