2015-07-10 36 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