First you need to include null fields in ExampleMatcher because default matcher does not include it.
Second if optional is null you need to exclude this field.
Short, you can write a method like this:
public static Example<User> getExampleByUserFilter(UserFilter userFilter) { User user = new User(); ExampleMatcher exampleMatcher = ExampleMatcher.matchingAll() .withIgnorePaths("id") // (1) .withIncludeNullValues(); Optional<String> optionalF1 = userFilter.getF1(); if (optionalF1.isPresent()) { if (!optionalF1.get().isBlank()) { user.setF1(optionalF1.get()); } } else { exampleMatcher = exampleMatcher.withIgnorePaths("f1"); } Optional<String> optionalF2 = userFilter.getF2(); if (optionalF2.isPresent()) { if (!optionalF2.get().isBlank()) { user.setF2(optionalF2.get()); } } else { exampleMatcher = exampleMatcher.withIgnorePaths("f2"); } // other fields .. return Example.of(user, exampleMatcher); }
Let's make an example and look at the sql query output:
... UserFilter userFilter1 = new UserFilter( Optional.of("f1"), Optional.empty(), Optional.of("f3")); UserFilter userFilter2 = new UserFilter( Optional.of("f1"), Optional.of(""), Optional.of("f3")); userRepository .findAll(getExampleByUserFilter(userFilter1)); userRepository .findAll(getExampleByUserFilter(userFilter2)); ...
The console output for this example:
Hibernate: select ... from user user0_ where user0_.f1=? and user0_.f3=? Hibernate: select ... from user user0_ where user0_.f1=? and user0_.f3=? and (user0_.f2 is null)
(1) The important thing here is that you need to eliminate all the fields that you will not use in the filter with withIgnorePaths(...) in the first step.
OR
I recommend using Specifications and Querydsl for such conditional operations.
You can extends from JpaSpecificationExecutor too and get the Predicate with QueryByExamplePredicateBuilder from Example.