Избегать N+1 выбора с родным sqlQuery?
Вот что у меня есть:
Entity A -> oneToMany -> Entity B -> manyToOne -> Entity C
И поскольку мне нужно выполнить внутреннее соединение без внешних ключей между A и другим объектом X, я должен использовать createSqlQuery, а не createQuery. (очевидно, я не могу изменить базу данных)
Итак, все, что я смог сделать, это хороший выбор 2N+1. (с fetch=EAGER или вручную, это то же самое).
У кого-нибудь есть идеи?
РЕДАКТИРОВАТЬ: с @BatchSize я сократил количество выборов с А до Б. Теперь у меня есть N+2 выбора.
РЕДАКТИРОВАТЬ 2: я не могу использовать внутреннее объединение (с запятой), потому что база данных является старой DB2, и она дает сбой.
3 ответа
Чтобы избежать N+1, вы можете использовать следующий код в поле карты
@Fetch(FetchMode.JOIN)
Надеюсь, это поможет.
Вы можете использовать что-то вроде этого, но я не уверен, как это будет работать со сложным запросом:
s.createSQLQuery(
"SELECT {a.*}, {b.*}, {c.*} " +
"FROM X x JOIN A a ON ... JOIN B b ON ... JOIN C c ON ...")
.addEntity(A.class, "a")
.addJoin(B.class, "a.b")
.addJoin(C.class, "a.b.c")
Смотрите также:
Извините за смутный ответ, я действительно никогда не испытывал этого. Я хотел бы попытаться подойти к этой проблеме, используя ResultTransformers:
http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/transform/ResultTransformer.html
К сожалению, документации об этом мало, поэтому лучше всего посмотреть на набор тестов и посмотреть, как он используется.