You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Andrus Adamchik <an...@objectstyle.org> on 2007/06/12 07:35:21 UTC
control select joins with EJBQL
We had extensive discussions with Mike K. on advanced join semantics
(and its limitations) in Cayenne. Here is a solution to controllable
joins coming from the JPA work. Let's say we are selecting artists
who have both paintings "P1" and "P2". You can't do it with
SelectQuery, as Cayenne would remove joins that it thinks are
"redundant".
String ejbql = "SELECT a "
+ "FROM Artist a JOIN a.paintingArray b JOIN a.paintingArray c "
+ "WHERE b.paintingTitle = 'P1' AND c.paintingTitle = 'P2'";
List artists = context.performQuery(new EJBQLQuery(ejbql));
This generates the following SQL - something you can't do with
SelectQuery:
SELECT t0.ARTIST_NAME AS ARTIST_NAME, t0.ARTIST_ID AS ARTIST_ID,
t0.DATE_OF_BIRTH AS DATE_OF_BIRTH
FROM ARTIST AS t0
INNER JOIN PAINTING AS t1 ON (t0.ARTIST_ID = t1.ARTIST_ID)
INNER JOIN PAINTING AS t2 ON (t1.ARTIST_ID = t2.ARTIST_ID)
WHERE t1.PAINTING_TITLE = ? AND t2.PAINTING_TITLE = ? [bind: 'P1',
'P2']
This is based on the code that I checked in last night. Note that it
works in "Cayenne classic" environment (not just JPA). I am still
working on handling and testing various edge cases, but the syntax
above works already.
Andrus
Re: control select joins with EJBQL
Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 12, 2007, at 8:35 AM, Andrus Adamchik wrote:
> SELECT t0.ARTIST_NAME AS ARTIST_NAME, t0.ARTIST_ID AS ARTIST_ID,
> t0.DATE_OF_BIRTH AS DATE_OF_BIRTH
> FROM ARTIST AS t0
> INNER JOIN PAINTING AS t1 ON (t0.ARTIST_ID = t1.ARTIST_ID)
> INNER JOIN PAINTING AS t2 ON (t1.ARTIST_ID = t2.ARTIST_ID)
> WHERE t1.PAINTING_TITLE = ? AND t2.PAINTING_TITLE = ? [bind:
> 'P1', 'P2']
Umm... looking at the SQL, there's still a bug - the condition must
be "(t0.ARTIST_ID = t2.ARTIST_ID)" in the second join. Coincidentally
this particular query still works, but I need to fix the translator.
Still the point remains - we now have a great deal of control over
the joins.
Andrus
Re: control select joins with EJBQL
Posted by Mike Kienenberger <mk...@gmail.com>.
Andrus,
There are some unit tests for outer joins that I created while I was
doing my own patch.
Maybe these can be reused. I'm pretty sure they're included in the
outer join jira issue.
On 6/12/07, Andrus Adamchik <an...@objectstyle.org> wrote:
> We had extensive discussions with Mike K. on advanced join semantics
> (and its limitations) in Cayenne. Here is a solution to controllable
> joins coming from the JPA work. Let's say we are selecting artists
> who have both paintings "P1" and "P2". You can't do it with
> SelectQuery, as Cayenne would remove joins that it thinks are
> "redundant".
>
> String ejbql = "SELECT a "
> + "FROM Artist a JOIN a.paintingArray b JOIN a.paintingArray c "
> + "WHERE b.paintingTitle = 'P1' AND c.paintingTitle = 'P2'";
>
> List artists = context.performQuery(new EJBQLQuery(ejbql));
>
> This generates the following SQL - something you can't do with
> SelectQuery:
>
> SELECT t0.ARTIST_NAME AS ARTIST_NAME, t0.ARTIST_ID AS ARTIST_ID,
> t0.DATE_OF_BIRTH AS DATE_OF_BIRTH
> FROM ARTIST AS t0
> INNER JOIN PAINTING AS t1 ON (t0.ARTIST_ID = t1.ARTIST_ID)
> INNER JOIN PAINTING AS t2 ON (t1.ARTIST_ID = t2.ARTIST_ID)
> WHERE t1.PAINTING_TITLE = ? AND t2.PAINTING_TITLE = ? [bind: 'P1',
> 'P2']
>
> This is based on the code that I checked in last night. Note that it
> works in "Cayenne classic" environment (not just JPA). I am still
> working on handling and testing various edge cases, but the syntax
> above works already.
>
> Andrus
>
>
>
>
>
>