没有懒惰地初始化角色集合:com.pojo.Student.phonenos,没有会话或会话被关闭

问题描述 投票:6回答:1

我正在使用注释学习hibernate映射。我已经完成了一个部分。即保存父表时,我可以自动插入子类。 see_that

但是当我获取主表时,我没有得到子表。也出错了

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

我的代码已添加到此处以供您查看。请仔细阅读。并给我很好的建议。 Student.java。 (父类)

@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(子类)

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

我的道教班

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

输出是

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

这里我使用的是单向(外键)一对多映射(不是联合表,双向)。

总结我的问题

1)当我们获取父表时如何获取子表,反之亦然

2)什么是渴望和懒惰的获取。

3)在一对多映射的情况下单向,双向和连接表,其中一个更加充满电。

hibernate annotations lazy-loading one-to-many lazy-initialization
1个回答
5
投票

1)

如果您希望每次检索到这些类的任何实体时都这样做,请在FetchMode.EAGER关联中指定@OneToMany@ManyToOne默认是渴望的。请注意,如果您只需要在特定情况下获取这些实体,这可能在很大程度上无效。如果是这种情况,你必须像你正在做的那样,但要确保检索Student对象的会话仍然是打开的。看到你正在使用Spring,你是否尝试使用@Transactional注释你的DAO /服务,以便在方法执行期间会话保持活动状态?或者您尝试过使用Hibernate.execute(),如下所示:

   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)看看这个问题:Difference between FetchType LAZY and EAGER in Java persistence?

3)这取决于你需要什么。如果您只需要以一种方式导航关联,那么只能以这种方式单向定义它。如果你需要两者,那就做两件事。 Join Table更多地与数据库设计有关。如果你想在Phone表中有一个FK,并且引用了手机所属的Student,或者你想要一个连接表,每个Phones都有Student

© www.soinside.com 2019 - 2024. All rights reserved.