2015-07-10 78 views
0

我使用Spring Data Jpa和Hibernate是提供者。加载父项时热切取孩子

我有一个父类映射如下:

@Entity 
@Table(name="parent") 
public class Parent { 

    private List<Child> childs; 
    private List<AnotherChild> anotherChilds; 

    @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER) 
    public List<Child> getChilds() { 
     return childs; 
    } 

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY) 
    public List<AnotherChild> getAntoherChilds() { 
     return anotherChilds; 
    } 

} 

和儿童:

@Entity 
@Table(name="child") 
public class Child { 

    private Parent parent; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "column_name") 
    public Parent getParent() { 
     return patern; 
    } 

} 

@Entity 
@Table(name="another_child") 
public class AnotherChild { 

    private Parent parent; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "column_name") 
    public Parent getParent() { 
     return patern; 
    } 

} 
  • 当我从数据库装载父,它不会加载的 名单孩子马上和
  • 当我调用parent.getChilds(),它返回 null。

你能提供一些建议吗?我错了吗?谢谢。

编辑:

经过一番研究,我发现,当我只有一个孩子,它急切地加载(如它应该)。但是,当我有多个孩子时,它不会 - 即使它已被标记为FetchType.EAGER和其他FetchType.LAZY。

注意:如果我将它们都标记为FetchType.EAGER,它将抛出MultipleBagFetchException:无法同时获取多个包。

同样的事情发生时,我将其标注为使用@Fetch(FetchMode.JOIN)语句

+2

尝试添加两个类的表名实体注释 –

+0

实际上它已经是一个实体。我更新了我的问题。 – dkakunsi

+0

如果您打算使用特定于Hibernate的注释,则可以将@ org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.JOIN)添加到一对多字段中。这将强制Hibernate加载父项的子项。 – manish

回答

2

如果添加Entity注解parent.getChilds()不应该作为你做实体empty.it会更好。

@Entity 
    @Table(name="PARENT_TBL") 
    public class Parent { 
     //other fields 
     @OneToMany(mappedBy = "parent",fetch = FetchType.LAZY,cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE},orphanRemoval = true) 
     private List<Child> childs; 
     //getter setter   
    } 


    @Entity 
    @Table(name="CHILD_TBL") 
    public class Child { 
    //other fields 
     @ManyToOne(fetch = FetchType.LAZY) 
     @JoinColumn(name = "PARENT_ID") 
     private Parent parent; 
    //getter setter 

} 

示例获取父查询;

public Parent getParent(long parentId) throws Exception { 
    session = sessionFactory.openSession(); 
     Criteria cr = session.createCriteria(Parent.class, "parent"); 
     cr.setFetchMode('parent.childs', FetchMode.JOIN); 
     cr.add(Restrictions.eq("parent.id", parentId)); 
     Parent parent = cr.uniqueResult(); 
     tx = session.getTransaction(); 
     session.beginTransaction(); 
     tx.commit(); 
    return parent; 

EAGER加载的集合意味着它们在提取父代时被完全提取。因此,如果您有Parent并且它有List,那么在提取Parent时从数据库中提取所有的孩子。

另一方面,LAZY表示只有在尝试访问列表时才会提取列表的内容。例如,通过调用parent.getChilds()。iterator()。调用List上的任何访问方法将启动对数据库的调用以检索元素。这是通过在列表(或设置)周围创建代理来实现的。因此,对于懒惰集合,具体类型不是ArrayList和HashSet。

+0

我需要父母是loaeded时的孩子。因为会议将在此后关闭。 – dkakunsi

+0

增加了getParent()查询。 – ozgur

+0

感谢您的查询,@ jackk。但我实际上使用Spring Data JPA,并试图不使用额外的会话管理。所以,如果我可以在实体映射中配置它,那将会很好。 – dkakunsi