As Ken Chan said, you can't do it directly in a single HQL query.
Concerning your three possibilities:
- Native SQL: Not recommendable. The syntax for outer joins is quite different between different databases.
- Add a relationship: That's what I would do. It does not cost much code or memory and it is quickly programmed.
- Inner join: That does not work (missing rows) if the relation really is an outer join in the database.
If by any special reasons you really don't want to add the relationship, you can split the query into two individual queries and join the result manually in java, for example like this:
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 */
...
}
This solution has (nearly) the same cost in execution time and memory as the outer join in the database (solution 2.). It is just a little bit more java code.
(The solution is similar to that one proposed by Ken Chan, but it avoids the "not in" and the inner select, which both can be inefficient in the database.)