Избегать N + 1 выбора с родным sqlQuery? - PullRequest
0 голосов
/ 09 марта 2011

Вот что у меня есть:

Entity A -> oneToMany -> Entity B -> manyToOne -> Entity C

И поскольку мне нужно выполнить внутреннее соединение без внешних ключей между A и другим объектом X, я должен использовать createSqlQuery, а не createQuery. (очевидно, я не могу изменить базу данных)

Итак, все, что мне удалось сделать, - это хороший выбор 2N + 1. (с помощью fetch = EAGER или вручную, то же самое).

У кого-нибудь есть идеи?

РЕДАКТИРОВАТЬ: с @BatchSize я сократил количество выборок с A до B. Теперь у меня N + 2 выбора.

РЕДАКТИРОВАТЬ 2: я не могу использовать внутреннее соединение (с запятой), потому что база данных - это старая DB2, и она дает сбой.

Ответы [ 3 ]

1 голос
/ 10 марта 2011

Чтобы избежать N + 1, вы можете использовать следующий код в поле вашей карты

@ Fetch (FetchMode.JOIN)

Надеюсь, это поможет.

0 голосов
/ 09 марта 2011

Извините за смутный ответ, я действительно никогда не сталкивался с этим. Я бы попытался подойти к этой проблеме, используя ResultTransformers:

http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/transform/ResultTransformer.html

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

0 голосов
/ 09 марта 2011

Вы можете использовать что-то подобное, но я не уверен, как это будет работать со сложным запросом:

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")

См. Также:

...