Я работаю над спецификацией JPA, которая должна сделать выбор на вводе.
У меня есть Entity Department , у которого есть поле code выглядит как DB001 ..
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnore
private Set<Employee> departments;
Также Сотрудник
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "departmentId")
@JsonIgnore
private Department department;
И мой тестовый контроллер для сотрудника
@GetMapping("/employee")
public List<Employee> getAllEmployee() {
final List<SearchData> searchDataList = new ArrayList<>();
searchDataList.add(new SearchData("name", "Ivan"));
searchDataList.add(new SearchData("code", "01"));
return employeeService.getDynamicEmployeeSearch(searchDataList);
}
Когда я открываю это в браузере, он говорит мне
Unable to locate Attribute with the the given name [name] on this ManagedType [com.mentor.jpa.dynamicquery.domain.Department]; nested exception is java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [name] on this ManagedType [com.mentor.jpa.dynamicquery.domain.Department]
Я понимаю, что имя атрибута существует только в Employee сущности и не существует в Department , но мне нужно сделать выбор с двумя или двумя критериями, поэтому они должны работать и то и другое. (Когда я пробую один критерий или критерии, которые не нуждаются в объединении, они работают!)
Что я должен изменить в своем коде Спецификация , чтобы объединение работало корректно. Мой код на Спецификация
@Override
public Predicate toPredicate(final Root<Employee> root, final CriteriaQuery<?> query,
final CriteriaBuilder criteriaBuilder) {
if (searchData != null) {
return criteriaBuilder.like(criteriaBuilder.lower(root
.join("department")
.get(searchData.getFieldName())
.as(String.class)),
"%" + searchData.getValue().toLowerCase() + "%");
}
return null;
}
P.S. класс SearchData - это просто pojo с
private String fieldName;
private String value;
А также мой метод из Службы Служащих
public List<Employee> getDynamicEmployeeSearch(List<SearchData> searchDataList) {
List<Employee> employeesList = new ArrayList<>();
Specification<Employee> specification = new EmployeeSpecification();
if (searchDataList != null) {
for (SearchData data : searchDataList) {
specification = Specification.where(specification).and(new EmployeeSpecification(data));
}
employeesList = employeeRepository.findAll(specification);
return employeesList;
}
return employeesList;
}
Мне нужно вернуть сотрудников с именем (или его частью, которую я ввожу в SearchData, И с кодом отдела, который я ввожу во второй SearchData, но этот код находится в другой таблице, имеющей отношения OneToMany