I have currently implemented a dynamic query builder that works perfectly if my query conditions are spelled correctly. Since this might not be always the case I need a solution that is flexible enough to take any variation of the condition, primarily supporting case insensitivity.
Current specification's toPredicate method override code looks like this:
final List<Predicate> predicates = new ArrayList<Predicate>();
Path<String> username = root.get("username");
Path<String> agentCode = root.get("agentCode");
Path<EntityStatus> status = root.get("status");
Path<String> firstname = root.get("firstName");
Path<String> lastname = root.get("lastName");
Path<String> email = root.get("eMail");
if(criteria.getUsername()!=null && !criteria.getUsername().isEmpty()) {
predicates.add(cb.equal(username, criteria.getUsername()));
}
if(criteria.getAgentCode()!=null && !criteria.getAgentCode().isEmpty()) {
predicates.add(cb.equal(agentCode, criteria.getAgentCode()));
}
if(criteria.getFirstName()!=null && !criteria.getFirstName().isEmpty()) {
predicates.add(cb.like(firstname, "%"+criteria.getFirstName()+"%"));
}
if(criteria.getLastName()!=null && !criteria.getLastName().isEmpty()) {
predicates.add(cb.equal(lastname, criteria.getLastName()));
}
if(criteria.getEMail()!=null && !criteria.getEMail().isEmpty()) {
predicates.add(cb.equal(email, criteria.getEMail()));
}
if(criteria.getStatus()!=null) {
predicates.add(cb.equal(status, criteria.getStatus()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
And my repository interface that is being called from the service layer looks like this.
public interface UserRepo extends PagingAndSortingRepository<User, Long> {
List<User> findAll(Specification spec);
}
Overview Spring Data JPA queries, by default, are case-sensitive. In other words, the field value comparisons are case-sensitive. In this tutorial, we'll explore how to quickly create a case insensitive query in a Spring Data JPA repository.
Case-insensitive: It means the text or typed input that is not sensitive to capitalization of letters, like “ Geeks ” and “ GEEKS ” must be treated as same in case-insensitive search. In Javascript, we use string.match () function to search a regexp in a string and match () function returns the matches, as an Array object.
IgnoreCase for Case Insensitive Queries Now, suppose we want to perform a case-insensitive search to find all passengers with a given firstName. To do so, we'll define our PassengerRepository as: Here, the IgnoreCase keyword ensures that the query matches are case insensitive.
Normally, you achieve the case-insensitivity with using method equalsIgnoreCase (). However in this case you just parse values to be compared without implementing the comparison itself. Thus you can parse all the values in lower-case using the method toLowerCase () forcing them to be compared case insensitively.
As @Nikolas Charalambidis has suggested, I've used a variation of his answer that is suitable for my exact implementation. The answer required modifying only predacate.add() lines. With this answer the solution is flexible enough to support both case insensitivity as well as partial input.
predicates.add(cb.like(cb.lower(email), "%"+criteria.getEMail().toLowerCase()+"%"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With