I have this examples ,but I can't solved difference between them. Both of them are creating same query.
public static Specification<TransactionProjection> hasDestinationPartyNumber(List<PartyNumber> values) {
if (CollectionUtils.isEmpty(values)) return not();
return (root, query, cb) -> cb.isTrue(root.get(TransactionProjection_.column1).in(values));
}
public static Specification<TransactionProjection> hasNotDestinationPartyNumber(List<PartyNumber> values) {
if (CollectionUtils.isEmpty(values)) return not();
return (root, query, cb) -> cb.isFalse(root.get(TransactionProjection_.column1).in(values));
}
Note that I haven't tested my answer, and isTrue(...)/isFalse(...)
is poorly documented.
I think the reason why isTrue(...)/isFalse(...)
has no effect in your example is that logical tests in SQL (and, by extension, in JPQL/Criteria API, in order for it to be easily translatable to SQL) do not have a boolean value (in fact, they are not r-values at all). For instance, the expression WHERE (a IN (1, 2, 3)) = TRUE
is invalid, since the a IN (1, 2, 3)
part does not evaluate to anything.
isTrue(...)/isFalse(...)
is meant to be applied to expressions that have an actual value. For example, if the TransactionProjection
entity had a boolean active
property, then it would make sense to use cb.isTrue(root.get(TransactionProjection_.active))
or cb.isFalse(root.get(TransactionProjection_.active))
.
I'm surprised that a query syntax exception wasn't thrown in your example, though, it might be a bug of the JPA implementation.