2009-09-02 57 views
2

每本書都可以有許多作者。每個作者可以編寫很多書。渴望加載多對多的關係 - Grails(GORM)

class Book { 
    static belongsTo = Author 
    static hasMany = [authors:Author] 
} 

class Author { 
    static hasMany = [books:Book] 
} 

現在,我什麼時候可以這樣做:

def book = Book.get(id) 
def authors = book.authors 

現在我想我應該能夠採取每個作者和獲得的書籍,他與有關:

authors.each { 
    it.books 
} 

你看現在它會得到遞歸(導致stackoverflow)。有人知道它是如何工作的嗎?

回答

1

無論是急於加載還是懶惰加載,一旦加載了Hibernate管理的實例,它就會保存在Hibernate Session中,這是它的第一級緩存(如果您還配置了第二級緩存,那麼實例也會在那裏,如果他們以前加載可能來自那裏)。

因此,加載了書籍,然後加載了它的作者集合(默認爲Set),每個作者的書已經在Session中,因此不需要去數據庫。

急切地加載映射集合使用初始結果集來獲取頂級實例和一個數據庫查詢中的子實例。懶惰地加載集合只需要第二個數據庫查詢來填充集合,但它具有僅在需要時加載集合的好處。

+0

因此,當我加載Book1時,Book1的所有作者,例如Author1,Author2等,因此所有由這些作者寫的書也將被加載到會話中。是對的嗎? – Langali 2009-09-02 02:54:16

+1

我不確定Grails如何配置Hibernate支持的「最大提取深度」,但對於兩個類肯定它應該可以正常工作。如果您爲書籍的作者和作者的書籍指定了提前抓取,那麼它會爲您加載所有內容。這可能很昂貴 - 如果您加載由編寫許多書籍的作者編寫的書籍,加載兩個表格的每個元素都不會花費太多。應該很少使用預加載,因爲每次加載實例時都不需要每個子集合的每個實例,所以延遲加載的整體性能更好。 – 2009-09-02 11:44:32