Reputation: 13151
What is a jpql equivalent of following SQL query :
select * from App left outer join App_Child on (App.id=App_Child.id and App_Child.status = 'active') where App.status='active' and App.id=1;
Sample Data:
ij> select * from App;
ID |STATUS
----------------------
1 |active
2 |active1
3 |active3
5 |active
4 rows selected
ij> select * from App_Child;
ID |STATUS |D
----------------------------------
1 |active |1
2 |active11 |2
1 |active111 |3
1 |active |4
4 rows selected
ij> select * from App left outer join App_Child on (App.id=App_Child.id and App_Child.status = 'active') where App.status='active' and App.id=1;
ID |STATUS |ID |STATUS |D
---------------------------------------------------------
1 |active |1 |active |1
1 |active |1 |active |4
2 rows selected
ij> select * from App left outer join App_Child on (App.id=App_Child.id and App_Child.status = 'active') where App.status='active' and App.id=5;
ID |STATUS |ID |STATUS |D
---------------------------------------------------------
5 |active |NULL |NULL |NULL
1 row selected
EDIT : We are using jpa 2.0
Upvotes: 7
Views: 4818
Reputation: 7141
If you want a SQL query to find all App's that have an "active" App_Child you could try exists instead of join.
-- Alternative SQL to join
select a.* from App a where a.ID = 1 and exists (select * from App_Child b where a.id=b.id AND b.STATUS = 'active')
In your example you had two things going on. In the SQL example on this page you're just getting the columns from the App table. On your fiddle though you're getting columns from the App table as well as the App_Child with only the "active" child rows shown. This exists method will work for the first query where you just want to retrieve the App but if you want to fetch both the App and child together then it won't help.
What you could do though is add a method to the App entitiy to get a collection of Active App_Child and map an appropriate property. You can get the App's you want using this "exists" query and then call getActiveChildren on each App.
I tested the SQL on your fiddle, here is the edit: http://sqlfiddle.com/#!4/0f39a/6/2
This reference shows you exists in JPQL. http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/jpa_langref.html#jpa_langref_exists
Hopefully that's enough info for you to try it out.
Upvotes: 0
Reputation: 4571
The condition App.id=App_Child.id
is automatically added because of the @ManyToOne
relation. And in JPA 2.1, you can add additional conditions with an explicit on
clause:
select a
from App a left outer join
a.children c on (c.status = 'active')
where a.status='active' and a.id=1;
See for example EclipseLink Documentation.
Upvotes: 8