无法对JpaSpecificationExecutor存储库使用findAll(规范,分页)方法。我将存储库接口设置为:
package com.task.task.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import com.task.task.domain.Employee;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>, JpaSpecificationExecutor<Employee> {
}
每当我调用EmployeeRepository.findall(规范,分页)时;抛出此错误:
"error": "Internal Server Error",
"exception": "org.springframework.beans.BeanInstantiationException",
"message": "Failed to instantiate [org.springframework.data.jpa.domain.Specifications]: No default constructor found;
nested exception is java.lang.NoSuchMethodException: org.springframework.data.jpa.domain.Specifications.<init>()",
"path": "/api/task/employee"
这是StackTrace:
2018-01-17 14:41:29.816 ERROR 12132 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.jpa.domain.Specifications]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.data.jpa.domain.Specifications.<init>()] with root cause
java.lang.NoSuchMethodException: org.springframework.data.jpa.domain.Specifications.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_144]
at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_144]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:102) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
完整代码:https://github.com/sanketkd/specificationexecutor
@Entity
@Table(name = "emp111")
public class Employee {
@Id
@Column(name = "employee_id")
private Long employeeId;
@Column(name = "ename", length = 20)
private String ename;
@Column(name = "hire_date")
private Date hireDate;
@Column(name = "salary")
private Long salary;
@Column(name = "skills", length = 30)
private String skills;
// getters setters
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.stereotype.Service;
import com.task.task.domain.Employee;
import com.task.task.repository.EmployeeRepository;
@Service
public class EmployeeService {
private final EmployeeRepository employeeRepository;
@Autowired
public EmployeeService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public Employee getEmployee(Long employeeId) {
return employeeRepository.findOne(employeeId);
}
public Page<Employee> getEmployees(Specifications<Employee> specifications, Pageable pageable) {
return employeeRepository.findAll(specifications, pageable);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.task.task.domain.Employee;
import com.task.task.service.EmployeeService;
@RestController
@RequestMapping("api/task/employee")
public class EmployeeController {
private final EmployeeService employeeService;
@Autowired
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
@RequestMapping(method = RequestMethod.GET, path = "/{employeeId:[0-9]\\d*}")
public Employee getEmployee(@PathVariable Long employeeId) {
return this.employeeService.getEmployee(employeeId);
}
@RequestMapping(method = RequestMethod.GET)
public Page<Employee> getEmployees(Specifications<Employee> specifications, Pageable pageable) {
return this.employeeService.getEmployees(specifications, pageable);
}
}
存储库:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import com.task.task.domain.Employee;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>, JpaSpecificationExecutor<Employee> {
}
您得到的异常与存储库无关,这是因为您在控制器中映射了specification
。这是不可能的,因为Spring不知道如何将传入的请求“解析”到specification
。它将尝试通过调用默认构造函数来构造规范
,但是由于没有默认构造函数,它将抛出一个异常。
您需要使用适当的请求体(或参数),并在控制器或服务中创建规范
而不是将其映射到控制器中。
使用Spring Boot2.x.x,您可以通过以下方式完成:
@RequestMapping(method = RequestMethod.GET)
public Page<Employee> getEmployees(
// Just plain parameters
@RequestParam String name,
@RequestParam int page,
@ResuestParam int limit) {
// Creating the specification
Specification<Employee> spec = Specification.where(EmployeeSpecs.employeeName(name));
// Creating the Pageable as well
Pageable pageable = PageRequest.of(page, limit);
return this.employeeService.getEmployees(specifications, pageable);
}
使用Spring Boot1.x.x,specification.where()
称为specifications.where()
。此外,PageRequest.of(..)
静态方法不存在,您应该使用New PageRequest(..)
构造函数。
使用分页已经有问题了。接受的解决方案适用于采用格式的查询。项目文档还引用了以下用法: https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.reactive.repositories.usage 例158。用于持久化个人实体的基本存储库接口 问题是这对findAll不起作用: 例外情况: Spri
我希望了解通用存储库模式。我有一个由抽象服务实现的通用服务接口,抽象服务由所有服务实现扩展。我希望确保所有CRUD操作和根据标准/规范进行的搜索都发生在抽象服务中。 我的所有存储库都是扩展JpaRepository和JPaspecificationExecutor的接口。但是,我不能在抽象服务中使用autowired存储库执行findAll(规范,分页)。 服务接口: 抽象服务: ServiceI
我需要获取所有可分页的文档,但我遇到了这个错误 com.fasterxml.jackson.databind.JsonMappingException:(java.lang.NullPointerException)(通过引用链:org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl["face
DTO筛选器类: 和搜索/筛选服务: 问题: 我使用的是Spring Boot 1.4(Spring 4.3.2,spring-data-jpa 1.10.2)和Hibernate 5.0.9
问题内容: 我有一个使用JOIN和ORDER BY的查询,并想使用Criteria Api在我的存储库中使用它。 在这里,我发现了如何将这样的查询包装到CriteriaQuery(Link)中。 另一方面,我发现了一些将Criteria Api与JpaRepository结合使用的示例(example)。 问题在于存储库中的所有方法都需要规范: 总是这样构建的: 因此,一方面,我知道如何创建Cri
我想在存储库中使用findAll方法,但我希望它只返回具有特定值的实体。例如,我希望它只返回活动的实体=1。有办法吗? 现在,我必须为我所有的存储库编写如下内容: 我没有使用findOne方法,而是在我所有的存储库中编写: 有没有更好的方法对所有查询应用一揽子过滤器?