my2iu / Jinq

LINQ-style queries for Java 8
Other
660 stars 71 forks source link

Add support to pass parameters in crossJoin #51

Open oberien opened 7 years ago

oberien commented 7 years ago

Is possible / feasible to implement crossJoin in a way that allows passing parameters while cross-joining?

Given these methods:

public JPAJinqStream<Customer> getCustomer(long id) {
    return streams.streamAll(em, Customer.class)
        .where(c -> c.getId() == id);
}

public JPAJinqStream<Sale> getSales(List<Long> ids) {
    return streams.streamAll(em, Sale.class)
        .where(s -> JPQL.isInList(s.getId(), ids));
}

Would it be possible to implement a crossJoin taking a lambda which takes the current type as parameter and returns the new stream to join with like this?

getCustomer(1337)
    .crossJoin(c -> getSales(c.getSales()));
my2iu commented 7 years ago

If you need a lambda, you can just use the normal join() syntax. I think it would be something like this:

getCustomer(1337).join(
    (c, source) -> source.stream(Sale.class)
        .where(s -> JPQL.isInList(s.getId(), c.getSales()) );
oberien commented 7 years ago

This case is highly simplified. In reality we are talking about both methods having 20+ lines of Jinq code. While I could copy the code and create a third method (which I will do if you say that this is not possible), it would be code duplication which I would like to avoid.

my2iu commented 7 years ago

It's not really possible since Jinq currently can't trace into other method calls when trying to decode a lambda.

You can maybe make a method that returns the lambda you need, but I'm not sure if that would work for your code. Something like

JoinWithSource<...> createJoin() {
   return (c, source) -> source.stream(Sale.class)
        .where(s -> JPQL.isInList(s.getId(), c.getSales())
}

getCustomer(1337).join( createJoin() );