jsr338-experts@jpa-spec.java.net

[jsr338-experts] JPQL joins and ON keyword

From: Steve Ebersole <steve.ebersole_at_redhat.com>
Date: Thu, 24 May 2012 14:09:12 -0500

I was not a member on the list when this was originally discussed, so I
apologize for dragging up a potentially old discussion. But I wanted to
caution against the use of 'ON' as a keyword in the way it is currently
proposed in the specification.

The problem is ambiguity in cases where the provider supports 'ON' as a
more SQL-like ad-hoc joining capability between unassociated entities.
In such cases the keyword 'ON' is often the only SYNTACTIC
disambiguation between the 2 cases.

Consider:

select s.name, count(p.id)
from javax.persistence.ex.Supplier s
     inner join javax.persistence.ex.Product p
         on s.id = p.supplierId

So here we have Supplier and Product as unrelated classes (no mapped
association). The problem is that structurally (syntactically) the
query is completely ambiguous with the proposed form:

select s.name, count(p.id)
from javax.persistence.ex.Supplier s
     inner join s.product
         on p.status = 'inStock'

where the join is an association join.

When parsing queries its always better to disambiguate based on syntax
whenever possible. Here we instead have to fall back to semantic
disambiguation, which essentially means that we now have to hold parsing
and interpret the meaning of the 2 sides of the join in oder to know
what type of join it is.

Not to mention that it is odd in my opinion for developers versed in SQL
to see ON used here. The first thought is whether that adds to the SQL
ON clause defined by the association mapping or whether that replaces
it. So we lose a little intuitiveness.

I'd really rather see a different keyword here. In Hibernate we chose
WITH as the keyword for this for just these reasons:

select s.name, count(p.id)
from javax.persistence.ex.Supplier s
     inner join s.product
         with p.status = 'inStock'

there I think it is very obvious that the condition is added to the SQL
ON clause.