New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sub query support #52
Comments
Did you try using WhereWithSource like this (untested)? streams.streamAll(Person.class)
.where((p, source) -> JPQL.isIn(p, source.stream(Friends.class)
.where(f -> f.getFromId() == personId)
.select(f -> f.getTo()))
) |
WorksInteresting progress. I tried it and it worked for that example. Thanks. stream
.where((p, source) -> JPQL.isIn(p.getId(),
source
.stream(Friends.class)
.where(f -> f.getFromId() == personId)
.select(l -> l.getToId())
))
.toList(); What doesn't workOur real query was a bit complex than what was posted involving a join in sub-query. I get this When I write // Method 1: just join
stream
.where((p, s) -> JPQL.isIn(p.getId(),
//Get Persons that are friends of friends
s
.stream(Friends.class)
.where(f -> f.getFromId() == personId)
.join((j, source) -> source.stream(Friends.class))
.where(j -> j.getOne().getToId().equals(j.getTwo().getFromId()))
.select(l -> l.getTwo().getToId())
))
//Method 2: Use sub query with a sub query
stream
.where((p, s) -> JPQL.isIn(p.getId(),
//Get Persons that are friends of friends
s
.stream(Friends.class)
.where(f -> f.getFromId() == personId)
.where((pp, ss) -> JPQL.isIn(pp.getFromId(),
ss.stream(Friends.class).where(ll -> branchIds.contains(ll.getFromId())).select(ll -> ll.getToId())
) )
.select(l -> l.getTwo().getToId())
)) QuestionYour insights would be greatly appreciated |
Oh, right. Sorry. I didn't get around to implementing |
Can you just add an association between friend objects? Apparently, I did implement support for
You mentioned that you encountered errors with paging when using distinct and join. What were those errors? Were they problems with EclipseLink/Hibernate or with Jinq? |
Oh, wait. I guess the query would be something more like
|
Hi @my2iu , Sorry for the delay. Tried theses approaches and here are the results. SelectAll() approach works if there is no
|
I don't really have the time to dig into these things and debug this. I'll try to find the time over my Easter holidays to add support for the What are the errors that you're encountering when using join and distinct when combined with paging and sorting? That really seems like something that might be easier to fix or workaround than to try to get complicated subquery expressions working with Jinq/Hibernate. |
Support for "with source" variants of join(), select(), selectAll(), and where() is done. I'll try to get around to making a new release with these changes on Monday or so. |
Jinq 1.8.18 with join() with source in subqueries has now been released. |
I tried 1.8.18, It sounded promising initially except the JPQL.isIn() part. I pulled the Github project and added sample test cases to reproduce the issues for you in 1.8.18. If you don't want to reopen this issue, I can create new Issues. But here is the reproducible test case for @Test
public void testJoinAndDistinct()
{
// Search Customers who purchased Widgets & Talents
List<String> names = new ArrayList<String>();
names.add("Widgets");
names.add("Talent");
// You may have Order Promotion codes or something in real life
List<Integer> quantities = new ArrayList<Integer>();
quantities.add(1);
quantities.add(2);
List<Customer> customers = streams.streamAll(em, Item.class)
.where(i -> names.contains(i.getName()))
.selectAll(i -> JinqStream.from(i.getLineorders()))
.select(lo -> lo.getSale())
.select(i -> i.getCustomer())
.sortedBy(c -> c.getName())
.distinct()
.toList();//Dies here
assertEquals("SELECT A FROM Customer A WHERE A.name IN (SELECT C.sale.customer.name FROM Item B JOIN B.lineorders C WHERE B.name IN :param0 AND C.quantity IN :param1) ORDER BY A.name ASC", query);
assertEquals(1, customers.size());//No idea fails here
assertEquals("Dave", customers.get(0).getName());
}
@Test
public void testIsInSubQueryWithSelectSourceRealLifeScenario()
{
// Search Customers who purchased Widgets & Talents
List<String> names = new ArrayList<String>();
names.add("Widgets");
names.add("Talent");
// You may have Order Promotion codes or something in real life
List<Integer> quantities = new ArrayList<Integer>();
quantities.add(1);
quantities.add(2);
List<Customer> customers = streams.streamAll(em, Customer.class)
.where((c, source) ->
JPQL.isIn(c.getName(), source.stream(Item.class)
.where(i -> names.contains(i.getName()))
.selectAll(i -> JinqStream.from(i.getLineorders()))
.where(i -> quantities.contains(i.getQuantity()))
.select(lo -> lo.getSale().getCustomer().getName())
))
.sortedBy(c -> c.getName())
.toList();
assertEquals("SELECT A FROM Customer A WHERE A.name IN (SELECT C.sale.customer.name FROM Item B JOIN B.lineorders C WHERE B.name IN :param0 AND C.quantity IN :param1) ORDER BY A.name ASC", query);
assertEquals(1, customers.size());//No idea why it throws error here
assertEquals("Dave", customers.get(0).getName());
} |
Both queries seem to mostly work for me, using both Hibernate and EclipseLink. For the The
Thanks for the additional test cases. I still need my garbage query test case because I need one with both multiple joins and a join with source variant used inside a subquery in order to exercise the part of Jinq that needs testing. It's hard to construct a query with those properties using the small database schema I use in the test database. |
Thanks it is correct. Swapping the order works. Yes, you need your garbage query. It is hard to construct queries with small DB schema, I faced the issue myself.. |
What needs to be done to support sub-queries like below so we don't get duplicate person records? JPQL seems to support this query format. Doing a JINQ's join and distinct seems to throw up errors when combined with paging and sorting.
The text was updated successfully, but these errors were encountered: