jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: outer joins with ON conditions

From: Emmanuel Bernard <emmanuel.bernard_at_jboss.com>
Date: Thu, 17 Mar 2011 09:30:55 +0100

On 16 mars 2011, at 20:15, Linda DeMichiel wrote:

>
>
> On 3/16/2011 3:46 AM, Emmanuel Bernard wrote:
>> On 15 mars 2011, at 19:16, Linda DeMichiel wrote:
>>> JPQL would be:
>>>
>>> FROM Cat as cat LEFT JOIN Kittens k ON k.bodyWeight > 10.0 AND k.parentName = cat.Name
>> But in this case, the SQL would be
>> from Cat c OUTER JOIN Kitten k ON c.id = k.parent AND c.name = k.parentName AND k.bodyWeight > 10.0
>> which is one to many clause for what the user wants to do.
>
> No, the above would not add c.id = k.parent to the SQL ON clause.
>
> Since we only defined JOIN that involves relationship navigation, we
> can make this distinction.
>

Got it now, sorry for having been dense :)

For completion, one case we would not be able to support is to map this full ON clause definition on an existing association at the object level.

Instead of:
String queryAssumingFullOnRewriting =
   "select c from Cat c left join fetch c.kittens on c.name = k.parentName AND k.bodyWeight > 10.0";
TypedQuery<Cat> cats = em.createQuery( queryAssumingFullOnRewriting ).getResultList();
for (Cat cat : cats) {
   Cat kittenJoinedByNameAndHealthy = cat.getKittens();
   doStuff(kittenJoinedByNameAndHealthy);
}

People would need to use tuples

String adHocOn =
    "select c,k from Cat c left join Cat k on c.name = k.parentName AND k.bodyWeight > 10.0";
TypedQuery<Tuple> cats = em.createQuery( adHocOn ).getResultList();
for (Tuple cat : cats) {
   Cat cat = (Cat) tuple.get(0);
   Cat kittenJoinedByNameAndHealthy = (Cat) tuple.get(1);
   doStuff(kittenJoinedByNameAndHealthy);
}

That's the only case I can think of when WITH vs ON could make sense.