speedment / jpa-streamer

JPAstreamer is a lightweight library for expressing JPA queries as Java Streams
GNU Lesser General Public License v2.1
344 stars 35 forks source link

Interopoptimizer should only squash adjacent filters and sorts that uses the JPAStreamer metamodel #355

Closed julgus closed 1 year ago

julgus commented 1 year ago

Describe the bug Adjacent operators of the same type that preserve {Order, Type, State, Side Effect} can be squashed into one single equivalent operator:

stream().filter(predicate1) .filter(predicate2) = stream.filter(predicate1.and(predicate2))

This allows JPAStreamer to combine many filters into one WHERE clause. However, as a filters can only be applied to the SQL query if it uses a JPAStreamer predicate, the squashed predicate must also be a combination of JPAStreamer predicates to be applied on the query. As of now, JPAStreamer squashes all predicates, resulting in more operations being executed on the JVM side.

Expected behavior Only adjacent filters using JPAStreamer predicates should be squashed.

Actual behavior Predicates are merged regardless of the predicate type.

How To Reproduce Run a query with two filters, one using a JPAStreamer predicate and one with an anonymous lambda. Observe in the Hibernate log that the first filter is not merged to the query. This happens as both filters are firsts squashed into an operator that cannot be merged into the query.

final List<Film> films = jpaStreamer.stream(Film.class)
                    .filter(Film$.length.greaterThan(120))
                    .filter(f -> f.getTitle().endsWith("A"))
                    .collect(Collectors.toList()); 

Build tool e.g. Maven 3.9.0

JPAStreamer version e.g. JPAStreamer 3.0.2