Присоединяйтесь по критериям, посторонний не хочет работать правильно - PullRequest
0 голосов
/ 16 января 2019

Я работаю над спецификацией 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

1 Ответ

0 голосов
/ 19 января 2019

решаемая. Написал переключение в toPredicate и добавил еще один предикат, и когда теперь у меня есть критерии из отдела, он выберет отдел, а когда из критерия сотрудник выберет сотрудника. В списке у меня есть правильные данные. Просто подумал, что для этого может быть что-то по умолчанию.

...