Стремительная загрузка с отношением «многие ко многим» — 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
}

Теперь вы видите, что это станет рекурсивным (что приведет к переполнению стека). Кто-нибудь знает, как это точно работает, когда он делает нетерпеливую выборку?


person Langali    schedule 02.09.2009    source источник


Ответы (2)


Независимо от того, загружается ли он с нетерпением или лениво, после загрузки экземпляра, управляемого Hibernate, он сохраняется в сеансе Hibernate, который является его кешем 1-го уровня (если вы также настроили кеш 2-го уровня, экземпляры также будут там и могут иметь приходят оттуда, если они были ранее загружены).

Таким образом, загрузив книгу, а затем загрузив ее авторскую коллекцию (Set по умолчанию), каждая авторская книга уже находится в сеансе, поэтому нет необходимости обращаться к базе данных.

Нетерпеливая загрузка сопоставленной коллекции использует начальный набор результатов для захвата экземпляра верхнего уровня и дочерних экземпляров в одном запросе к базе данных. Для ленивой загрузки коллекции требуется всего лишь второй запрос к базе данных для заполнения коллекции, но преимущество заключается в том, что коллекция загружается только при необходимости.

person Burt Beckwith    schedule 02.09.2009
comment
Поэтому, когда я с нетерпением загружаю Книгу 1, все авторы Книги 1, например, Автор 1, Автор 2 и т. Д. И, следовательно, все книги, написанные каждым из этих авторов, также будут загружены в сеанс. Это правильно? - person Langali; 02.09.2009
comment
Я не уверен, как Grails настраивает максимальную глубину выборки, которую поддерживает Hibernate, но, конечно, для двух классов это должно работать нормально. Если вы укажете нетерпеливую загрузку как для авторов книги, так и для книг автора, тогда он загрузит все для вас. Это потенциально затратно — загрузка каждого элемента обеих таблиц не займет много времени, если вы загружаете книгу, написанную автором, который пишет много книг. Стремительную загрузку следует использовать редко, потому что вам не часто требуется каждый экземпляр дочерней коллекции каждый раз, когда вы загружаете экземпляр, поэтому ленивая загрузка в целом работает лучше. - person Burt Beckwith; 02.09.2009

Для большей ясности вы можете обратиться к блогу Берта Беквита по адресу http://burtbeckwith.com/blog/?p=169, а также вы можете перейти по ссылке на презентацию, указанной в блоге.

person Amit Jain    schedule 02.09.2009