I\'m trying to see how I would create a JPA Critera query which allows for fully dynamic filtering with multiple levels.
For example
select *
from tabl
You need to create a Specification as in the test below. This can be dynamic.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=HelloWorldConfig.class)
public class SpecificationTest {
@Autowired
private AccountRepository repository;
@Test
public void test1() {
final List<String> names = Arrays.asList(new String[]{"George","Max"});
Specification<Account> specification = new Specification<Account>() {
public Predicate toPredicate(Root<Account> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<Predicate>();
predicates.add(root.get("name").in(names).not());
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
assertNotNull(repository);
repository.save(makeAccount("Greg", "123456787", "01-02-01"));
repository.save(makeAccount("George", "123456788", "01-02-02"));
repository.save(makeAccount("Max", "123456789", "01-02-03"));
List<Account> accounts = repository.findAll(specification);
assertEquals(1,accounts.size());
assertEquals("123456787",accounts.get(0).getAccountNumber());
}
private Account makeAccount(String name, String accountNumber, String sortCode) {
Account account = new Account();
account.setName(name);
account.setAccountNumber(accountNumber);
account.setSort(sortCode);
return account;
}
}
Where the repository looks like :
@Repository
public interface AccountRepository extends JpaRepository<Account, Long>, JpaSpecificationExecutor<Account> {
}