Alias in JPQL fetch join

The JPA spec does NOT allow an alias to be given to a fetch join in JPQL:

Select c from Contact c join fetch c.phones p where p.areaCode = '416';

They don't allow alias because it is easy to get confused as the following:

For:

Select c from Contact c join c.phones p where p.areaCode = '416';

This will return all contacts with "any" phone number in '416'. But when you check the returned contacts' phones, they include phones other than '416'.  If your expectation is that the returned phones should be only  those of area code '416', you may be surprise. This is because JPQL is object oriented. A specific contact should always have the same phones within the same persistence context. They should not be different just because you query in different way.
If you really want the contact, and only the phones of the area code '416', you can use the following query:

Select c, p from Contact c join c.phones p where p.areaCode = '416';


You can try nested join fetch through the query hint:

query.setHint(QueryHints.FETCH, "c.phones")

But it is better to also set

query.setHint("javax.persistence.cache.storeMode", "BYPASS");

query.setHint("javax.persistence.cache.retrieveMode", "BYPASS");

to avoid corrupting the shared cache. Because the contacts returned by this way only have phones of area code '416'.

Comments

Popular posts from this blog