I am trying to implement a filter functionality in a Spring Boot App, but it fails when I try to filter based on an integer.
public class StudentSearchCriteria {
private String firstName;
private String lastName;
private Integer yearOfStudy;
}
public class StudentPage {
private int pageNumber = 0;
private int pageSize = 1;
private Sort.Direction sortDirection = Sort.Direction.ASC;
private String sortBy = "lastName";
}
public class StudentCriteriaRepository {
private final EntityManager entityManager;
private final CriteriaBuilder criteriaBuilder;
public StudentCriteriaRepository(EntityManager entityManager) {
this.entityManager = entityManager;
this.criteriaBuilder = entityManager.getCriteriaBuilder();
}
public Page<Student> findAllWithFilters(StudentPage studentPage,
StudentSearchCriteria studentSearchCriteria) {
CriteriaQuery<Student> criteriaQuery = criteriaBuilder.createQuery(Student.class);
Root<Student> studentRoot = criteriaQuery.from(Student.class);
Predicate predicate = getPredicate(studentSearchCriteria, studentRoot);
criteriaQuery.where(predicate);
setOrder(studentPage, criteriaQuery, studentRoot);
TypedQuery<Student> typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setFirstResult(studentPage.getPageNumber() * studentPage.getPageSize());
typedQuery.setMaxResults(studentPage.getPageSize());
Pageable pageable = getPageable(studentPage);
long studentsCount = getStudentsCount(predicate);
return new PageImpl<>(typedQuery.getResultList(), pageable, studentsCount);
}
private Predicate getPredicate(StudentSearchCriteria studentSearchCriteria,
Root<Student> studentRoot) {
List<Predicate> predicates = new ArrayList<>();
if (Objects.nonNull(studentSearchCriteria.getFirstName())) {
predicates.add(
criteriaBuilder.like(studentRoot.get("firstName"),
"%" studentSearchCriteria.getFirstName() "%")
);
}
if (Objects.nonNull(studentSearchCriteria.getLastName())) {
predicates.add(
criteriaBuilder.like(studentRoot.get("lastName"),
"%" studentSearchCriteria.getLastName() "%")
);
}
if (Objects.nonNull(studentSearchCriteria.getYearOfStudy())) {
predicates.add(
criteriaBuilder.like(studentRoot.get("yearOfStudy"),
"%" studentSearchCriteria.getYearOfStudy() "%")
);
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
CodePudding user response:
JPA can't execute like
query between Integer
and String
. Try to convert Interger
to String
in yearOfStudy
if (Objects.nonNull(studentSearchCriteria.getYearOfStudy())) {
predicates.add(
criteriaBuilder.like(studentRoot.get("yearOfStudy").as(String.class), "%" studentSearchCriteria.getYearOfStudy() "%")
);
}