2010-08-02 61 views
3

我JAVE以下映射超類,它提供了基本實現了父/子自我關係創建項目的無限嵌套(即分類)Hibernate的父/子SELECT N + 1問題

@MappedSuperclass 
public abstract class ParentChildPathEntity<N extends ParentChild> implements MaterializedPath<N> { 


    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name = "parent_id") 
    private N parent; 

    @Column(name = "name", unique = true) 
    private String name; 

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    private Set<N> children = new HashSet<N>(); 
父/子列表

如果我加載整個表與父和孩子的讀取加入,一個選擇加載所有記錄,我可以愉快地遍歷樹。當我指定檢索樹上的節點時,我的問題就出現了。我希望節點及其所有孩子都能在一次選擇中完成。下面是加載整個表的HQL:

hql.append(String.format("tree from %s tree ", tableName)); 
hql.append("left join fetch tree.parent ");  
hql.append("left join fetch tree.children "); 

,如果我指定節點名稱,即:

where tree.name = :name 

然後冬眠檢索節點,但是當我訪問的孩子我得到的選擇N +1問題。我知道爲什麼會發生這種情況(因爲tree.name =:name),但是有沒有辦法編寫HQL,以便加載指定的節點及其所有子節點?

我只是試圖找出一種方法來支持一個簡單的嵌套項目的名單,我可以檢索與一個任何父節點及其子選擇提前

感謝,

回答

1

你試過使用@BatchSize註釋?

@BatchSize(size = 20) 

例:

@OneToMany(mappedBy = ..., fetch = FetchType.LAZY) 
@BatchSize(size = 20) 
public SortedSet<Item> getItems() { ... } 

然後,如果你指定連接到你的HQL的孩子,你應該能夠避免N + 1選擇。如果有辦法在HQL語句中指定批量大小,我不確定。

+0

嘿感謝很多,這真的提高了性能到可接受的水平..以爲我可能必須實現嵌套集,我沒有時間現在..再次感謝 – 2010-08-02 21:25:07