pas paresseusement initialiser une collection de rôle: com.pojo.Student.phonenos, aucune session ou session fermée

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

Question

J'apprends la cartographie de mise en veille prolongée en utilisant l'annotation. J'ai terminé une section. C'est à dire. Je peux insérer classe enfant automatiquement lorsque j'enregistre la table parent. see_that .

Mais je n'ai pas la table enfant quand je suis aller chercher la table principale. En outre obtenir une erreur

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

Mon code est ajouté ici pour vous revoir. S'il vous plaît passer par là. Et donnez-moi le grand conseil. Student.java. (Classe parent)

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

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

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

eteint est

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

J'utilise ici unidirectionnel (clé étrangère) une à plusieurs cartographie (pas à la table commune, bi-directionnel).

Summerizing ma question

1) comment obtenir la table des enfants quand nous récupérons la table parent, vice versa

2) ce qui est impatient et paresseux chercher.

3) unidirectionnelle, bidirection, et se joindre à la table dans le cas de la cartographie un à plusieurs que l'on est plus pleine puissance.

Était-ce utile?

La solution

1)

Si vous voulez vraiment faire cela chaque fois que toute entité de ces classes est récupérée, spécifiez FetchMode.EAGER dans l'association @OneToMany. @ManyToOne sont impatients par défaut. Sachez que cela pourrait être en grande partie unefficient si vous avez besoin d'aller chercher ces entités que dans des circonstances particulières. Si tel est le cas, vous devez le faire comme vous faites, mais assurez-vous que la session qui récupéré l'objet Student est encore ouvert. Voyant que vous utilisez Spring, avez-vous essayé annoter votre OAC / service avec @Transactional, de sorte que la session maintient en vie lors de l'exécution de la méthode? Ou avez-vous essayé d'utiliser Hibernate.execute(), comme ceci:

   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) Jetez un oeil à cette question: FetchType LAZY et Eager Java Persistence ?.

3) Cela dépend de ce dont vous avez besoin. Si vous ne devez naviguer dans l'association d'une manière, définir unidirectionnel de cette façon seulement. Si vous avez besoin à la fois, faire les deux. Joignez-vous à table a plus à voir avec la conception de base de données. Si vous voulez avoir un FK dans la table Phone avec la référence au Student le téléphone appartient, ou si vous voulez avoir une table de jointure avec le Phones de chaque Student.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top