Как сказал Кен Чан, вы не можете сделать это напрямую в одном запросе HQL.
Относительно ваших трех возможностей:
- Собственный SQL: не рекомендуется. Синтаксис внешних объединений в разных базах данных весьма различен.
- Добавить отношения: Я бы так и сделал. Он не требует больших затрат кода или памяти и быстро программируется.
- Внутреннее соединение: это не работает (пропущенные строки), если отношение действительно является внешним соединением в базе данных.
Если по каким-то особым причинам вы действительно не хотите добавлять отношения, вы можете разделить запрос на два отдельных запроса и вручную объединить результат в java, например, так:
Query qa = session.createQuery("from A a");
List la = qa.list();
Query qb = session.createQuery("select distinct b.* from B b, A a where a.some=b.some");
List lb = qb.list();
Map bMap = new HashMap();
for (B b : lb) {
bMap.put(b.getId(), b);
}
/* example with for loop */
for (A a : la) {
B b = bMap.get(a.getForeignKeyForB());
/* now you have A a and the outer joined B b and you can do with them what you want */
...
}
Это решение имеет (почти) ту же стоимость времени выполнения и памяти, что и внешнее объединение в базе данных (решение 2.). Это просто немного больше кода Java.
(Решение аналогично предложенному Кеном Чаном, но оно избегает «не в» и внутреннего выбора, которые оба могут быть неэффективными в базе данных.)