加入 criteriaBuilder 不想正常工作
Join at criteriaBuilder do not want to work correctly
我正在研究 JPA 规范,它必须根据我输入的内容生成 select。
我的实体 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 中,但我需要创建一个 select 有两个标准,所以他们需要同时工作。 (当我尝试一个或多个不需要连接的条件时,它们起作用了!)
我应该在我的 规范 代码中更改什么以使连接正确工作。我的代码在 Specification
@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。 class 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;
}
我需要 return 员工姓名(或者我在 SearchData 中输入的部分,以及我在第二个 SearchData 中输入的部门代码,但该代码在另一个 table 中,它有关系 OneToMany
已解决。
在 toPredicate 中写入 switch 并添加另一个谓词,现在当我有来自部门的标准时,它将 select 部门,当来自员工的标准时,它将 select 员工。
在列表中我有正确的数据。只是认为也许为此存在一些默认设置。
我正在研究 JPA 规范,它必须根据我输入的内容生成 select。 我的实体 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 中,但我需要创建一个 select 有两个标准,所以他们需要同时工作。 (当我尝试一个或多个不需要连接的条件时,它们起作用了!)
我应该在我的 规范 代码中更改什么以使连接正确工作。我的代码在 Specification
@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。 class SearchData 是
的简单 pojoprivate 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;
}
我需要 return 员工姓名(或者我在 SearchData 中输入的部分,以及我在第二个 SearchData 中输入的部门代码,但该代码在另一个 table 中,它有关系 OneToMany
已解决。 在 toPredicate 中写入 switch 并添加另一个谓词,现在当我有来自部门的标准时,它将 select 部门,当来自员工的标准时,它将 select 员工。 在列表中我有正确的数据。只是认为也许为此存在一些默认设置。