no pudo inicializar perezosamente una colección de roles: com.pojo.Student.phonenos, no se cerró ninguna sesión o sesión
-
27-10-2019 - |
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.
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
.