6

Sto imparando la mappatura in sospensione utilizzando l'annotazione. Ho completato una sezione. Cioè Posso inserire automaticamente la classe figlio quando salvi la tabella genitore. see_that.non è riuscito a inizializzare in modo lento una raccolta di ruoli: com.pojo.Student.phonenos, nessuna sessione o sessione è stata chiusa

Ma non ho ottenuto la tabella figlio quando sto recuperando la tabella principale. Anche ricevendo 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 è stato aggiunto qui per la revisione. Per favore, passa attraverso 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 figlia)

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

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

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 unidirezionale (chiave esterna) mappatura uno a molti (non j tavolo da biliardo, bidirezionale).

Summerizing mia domanda

1) come ottenere tabella figlio quando abbiamo recuperare la tabella padre, viceversa

2) ciò che è desideroso e pigro recupero.

3) unidirezione, bidirezione e tabella di join nel caso della mappatura uno a molti, di cui uno è più pieno.

risposta

5

1)

Se si vuole veramente fare questo ogni volta che qualsiasi entità di queste classi viene recuperato, specificare FetchMode.EAGER nel @OneToMany associazione. @ManyToOne sono desiderosi di impostazione predefinita. Tieni presente che questo potrebbe essere in gran parte inefficiente se hai bisogno di recuperare quelle entità solo in particolari circostanze. Se questo è il caso, 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 si mantenga attiva durante l'esecuzione del metodo? O avete provato ad 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) Date un'occhiata a questa domanda: Difference between FetchType LAZY and EAGER in Java persistence?.

3) Dipende da ciò di cui hai bisogno. Se hai solo bisogno di navigare l'associazione in un modo, definiscila unidirezionale solo in questo modo. Se hai bisogno di entrambi, fai entrambe le cose. La tavola dei join ha più a che fare con la progettazione del database. Se si desidera avere un FK nella tabella Phone con il riferimento allo Student al quale appartiene il telefono oppure si desidera disporre di una tabella di join con lo Phones di ogni Student.

+0

Il pice di codice non funziona ... getHibernateTemplate(). Execute (nuovo errore di compilazione HibernateCallback(). – jaleel

+0

Tnx. per il replay .. aspettando la soluzione. – jaleel

+0

Hai provato ad annotare il DAO o il metodo con '@ Transactional'? Hai un transactionManager nel tuo applicationContext.xml? –

Problemi correlati