Я получаю следующую ошибку:
InvalidDataAccessApiUsageException: Already registered a copy: SqmBasicValuedSimplePath
com.example.employee.model.Employee(1234567890).name)
Я создал приложение Spring Boot, которое выполняет сортировку, фильтрацию и разбиение по страницам. Все работает, кроме фильтрации, потому что у меня выскакивает эта ошибка, когда я пытаюсь фильтровать. Я объясню как.
Когда я печатаю
localhost:8080/employees/?name=ben
Я ожидаю, что в URL-адресе будут указаны сотрудники, имена которых совпадают с именем Бена. Я получаю ответ:
{
"status": 500,
"reason": "Already registered a copy: SqmBasicValuedSimplePath(com.example.employee.model.Employee(1234567890).name)",
"timeStamp": "11:16:33"
}
Однако это не приводит к ошибкам:
localhost:8080/employees/?nameeee=ben
Когда я использую неправильную/с ошибкой написанную переменную свойства, ошибок не возникает, и объекты извлекаются (без фильтрации), очевидно.
То, что я хочу, это чтобы вернуть объекты сотрудников, имя которых соответствует «Бен»
Ниже представлена моя модель критериев поиска:
@Data
public class EmployeeSearchCriteria {
private String name;
private String department;
}
Ниже представлен репозиторий моих критериев:
@Repository
public class EmployeeCriteriaRepo {
private final EntityManager entityManager;
private final CriteriaBuilder criteriaBuilder;
public EmployeeCriteriaRepo(EntityManager entityManager) {
this.entityManager = entityManager;
this.criteriaBuilder = entityManager.getCriteriaBuilder();
}
public Page findAllWithFilters(EmployeePage employeePage, EmployeeSearchCriteria searchCriteria) {
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Employee.class);
Root employeeRoot = criteriaQuery.from(Employee.class);
Predicate predicate = getPredicate(searchCriteria, employeeRoot);
criteriaQuery.where(predicate);
setOrder(employeePage, criteriaQuery, employeeRoot);
TypedQuery typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setFirstResult(employeePage.getPageNumber() * employeePage.getPageSize());
typedQuery.setMaxResults(employeePage.getPageSize());
Pageable pageable = getPageable(employeePage);
long employeesCount = getEmployeesCount(predicate);
return new PageImpl(typedQuery.getResultList(), pageable, employeesCount);
}
private long getEmployeesCount(Predicate predicate) {
CriteriaQuery countQuery = criteriaBuilder.createQuery(Long.class);
Root countRoot = countQuery.from(Employee.class);
countQuery.select(criteriaBuilder.count(countRoot)).where(predicate);
return entityManager.createQuery(countQuery).getSingleResult();
}
private Pageable getPageable(EmployeePage employeePage) {
Sort sort = Sort.by(employeePage.getSortDirection(), employeePage.getSortBy());
return PageRequest.of(employeePage.getPageNumber(), employeePage.getPageSize(), sort);
}
private void setOrder(EmployeePage employeePage,
CriteriaQuery query,
Root employeeRoot) {
if (employeePage.getSortDirection().isAscending()) {
query.orderBy(criteriaBuilder.asc(employeeRoot.get(employeePage.getSortBy())));
}
else {
query.orderBy(criteriaBuilder.desc(employeeRoot.get(employeePage.getSortBy())));
}
}
private Predicate getPredicate(EmployeeSearchCriteria searchCriteria, Root employeeRoot) {
List predicateList = new ArrayList();
if (Objects.nonNull(searchCriteria.getName())) {
predicateList.add(criteriaBuilder.like(
employeeRoot.get("name").as(String.class),
"%" + searchCriteria.getName() + "%")
);
}
if (Objects.nonNull(searchCriteria.getDepartment())) {
predicateList.add(criteriaBuilder.like(
employeeRoot.get("department").as(String.class),
"%" + searchCriteria.getDepartment() + "%")
);
}
return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
}
Подробнее здесь: https://stackoverflow.com/questions/742 ... pring-boot