impossibile inizializzare pigramente una raccolta di ruoli: com.pojo.Student.phonenos, nessuna sessione o sessione è stata chiusa

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

Domanda

Sto imparando la mappatura ibernata utilizzando l'annotazione. Ho completato una sezione. Cioè Posso inserire automaticamente la classe figlio quando salvo la tabella genitore. see_that .

Ma non ho ricevuto la tabella figlia durante il recupero della tabella principale. Ricevo anche un errore

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

Il mio codice viene aggiunto qui per esaminarti. Per favore, esaminalo. E dammi l'ottimo consiglio. Student.java. (classe genitore)

@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 figlio)

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

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

L'out put è

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

Qui sto usando la mappatura uno-a-molti unidirezionale (chiave esterna) (non tabella congiunta, bidirezionale).

Riassumendo la mia domanda

1) come ottenere la tabella figlia quando recuperiamo la tabella genitore, viceversa

2) ciò che è desideroso e pigro.

3) tabella unidirezionale, bidirezionale e di unione nel caso di mappatura uno-a-molti quale è più potente.

È stato utile?

Soluzione

1)

Se vuoi davvero farlo ogni volta che viene recuperata una qualsiasi entità di queste classi, specifica FetchMode.EAGER nell'associazione @OneToMany. @ManyToOne sono desiderosi per impostazione predefinita. Tieni presente che ciò potrebbe essere in gran parte inefficiente se devi recuperare quelle entità solo in circostanze particolari. Se è così, devi farlo come stai facendo, ma assicurati che la sessione che ha recuperato l'oggetto Student sia ancora aperta. Visto che stai usando Spring, hai provato ad annotare il tuo DAO / Servizio con @Transactional, in modo che la sessione rimanga viva durante l'esecuzione del metodo? Oppure hai provato a utilizzare Hibernate.execute(), in questo modo:

   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) Dai un'occhiata a questa domanda: Differenza tra FetchType LAZY e EAGER nella persistenza Java? .

3) Dipende da cosa ti serve. Se è necessario navigare l'associazione in un solo modo, definirla unidirezionale solo in quel modo. Se hai bisogno di entrambi, fallo entrambi. Join Table ha più a che fare con la progettazione del database. Se vuoi avere un FK nella tabella Phone con il riferimento al Student a cui appartiene il telefono, o vuoi avere una tabella join con il Phones di ogni Student.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top