I have a query where I expect 1000s of rows and I'm looking for values in two columns. Something like this
select
*
from
foo
WHERE
(name, version)
in
(('a','2.0.0'),('b','1.0.0'));
Then I learned that this is not possible in JPA and I converted the query to multiple OR
and AND
queries.
select
*
from
foo
WHERE
name = 'a' and version = '2.0.0'
or name = 'b' and version = '1.0.0'
I'm using a specification to build the query.
var predicates =
values.entrySet().stream()
.map(
entry -> {
return cb.and(
cb.equal(root.get("name"),entry.getKey()),
cb.equal(root.get("version"), entry.getValue()));
})
.toList();
return cb.or(predicates.toArray(Predicate[]::new));
That works but it's very slow and other answer support my findings.
- https://dba.stackexchange.com/questions/91247/optimizing-a-postgres-query-with-a-large-in
- Performance issue in update query
- https://dba.stackexchange.com/questions/129844/cross-product-between-table-column-and-input-values
So now I'm trying to do something like this.
select
*
from
(
values
('a', '2.0.0'),
('b', '1.0.0')
) t(name, version)
left join
foo
on t.name = foo.name and t.version = foo.version
Here is the official documentation.
https://www.postgresql.org/docs/current/queries-values.html
I'm having trouble translating this in to JPA or using a specification / criteria builder.
Any ideas? Or do I have to use a native query?
Thank you!