falha ao inicializar preguiçosamente uma coleção de papéis: com.pojo.Student.phonenos, nenhuma sessão ou sessão foi encerrada

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

Pergunta

Estou aprendendo o mapeamento de hibernação usando anotação. Concluí uma seção. Ou seja Posso inserir a classe filho automaticamente ao salvar a tabela pai. see_that .

Mas não obtive a tabela filho quando estou buscando a tabela mestre. Também obtendo um erro

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

Meu código foi adicionado aqui para revisar você. Por favor, vá em frente. E me dê um ótimo conselho. Student.java. (aula de pais)

@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 (classe filha)

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

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

A saída é

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

Aqui estou usando mapeamento um-para-muitos unidirecional (chave estrangeira) (não tabela conjunta, bidirecional).

Summerizing minha pergunta

1) como obter a tabela filho quando buscamos a tabela pai, vice-versa

2) o que é busca ansiosa e preguiçosa.

3) mesa unidirecional, bidirecional e de junção no caso de mapeamento Um-para-Muitos, que tem mais potência total.

Foi útil?

Solução

1)

Se você realmente deseja fazer isso toda vez que qualquer entidade dessas classes for recuperada, especifique FetchMode.EAGER na associação @OneToMany. @ManyToOne são ansiosos por padrão. Esteja ciente de que isso pode ser bastante ineficiente se você precisar buscar essas entidades apenas em circunstâncias específicas. Se for esse o caso, você deve fazer como está fazendo, mas certifique-se de que a sessão que recuperou o objeto Student ainda está aberta. Vendo que você está usando Spring, você tentou anotar seu DAO / Service com @Transactional, para que a sessão se mantenha viva durante a execução do método? Ou você já tentou usar 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) Dê uma olhada nesta questão: Diferença entre FetchType LAZY e EAGER na persistência Java? .

3) Depende do que você precisa. Se você só precisa navegar na associação de uma maneira, defina-a unidirecional apenas dessa maneira. Se você precisar de ambos, faça os dois. O Join Table tem mais a ver com o design do banco de dados. Se você deseja ter um FK na tabela Phone com a referência ao Student ao qual o telefone pertence, ou deseja ter uma tabela de junção com o Phones de cada Student.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top