загружающие запросы с помощью GORM / Hibernate - PullRequest
3 голосов
/ 17 сентября 2009

Приложение My Grails имеет следующие доменные объекты

class ProductType {
    String name
    static hasMany = [attributes: Attribute]
}

class Attribute {       
    String name
    static belongsTo = [productType: ProductType]
} 

Моя БД имеет 7 ProductType с, а каждая из них имеет 3 Attribute с. Если я выполню запрос:

def results = ProductType.withCriteria {
    fetchMode("attributes", org.hibernate.FetchMode.EAGER)
}

Я ожидаю, что будет возвращено 7 экземпляров ProductType, но на самом деле я получаю 21 (7 x 3). Я понимаю, что если бы я выполнил SQL-запрос, эквивалентный приведенному выше, результирующий набор имел бы 21 строку

prod1 | attr1
prod1 | attr2
prod1 | attr3
..... | .....
..... | .....
prod7 | attr1
prod7 | attr2
prod7 | attr3
-------------
Total 21

Но я подумал, что когда я получу эти результаты через Hibernate / GORM, я должен получить что-то похожее на:

prod1 | attr1, attr2, attr3    
..... | ...................
..... | ...................
prod7 | attr1, attr2, attr3
---------------------------
Total 7

Между прочим, если я удаляю нетерпеливую загрузку из запроса выше, я получаю 7 ProductType с, как и ожидалось. Чего мне не хватает?

1 Ответ

4 голосов
/ 22 сентября 2009

вы должны прочитать это faq: Hibernate не возвращает отличные результаты для запроса с включенной выборкой внешнего объединения для коллекции (даже если я использую отдельное ключевое слово)?

Когда вы указываете активную загрузку, результирующий набор содержит, как вы заметили, 7 * 3 строки, но на самом деле у вас есть только 7 объектов productTypes в памяти (& 2 дополнительных ссылки для каждой).
Чтобы сделать то, что вы хотите, вы можете добавить (имейте в виду, что базовый SQL-запрос не изменился):

SetResultTransformer(new DistinctRootEntityResultTransformer())

def results = ProductType.withCriteria {
    fetchMode("attributes", org.hibernate.FetchMode.EAGER)
    SetResultTransformer(new DistinctRootEntityResultTransformer())
}
...