Java 规范对象没有';即使在创建之后也不包含任何条件
在Spring数据JPA中创建动态搜索规范时面临问题 当我将源-目标或dispatchNumber值传递给下面实现的规范时,返回的规范对象不包含任何条件(请参阅)。然而,第三方和自始至终的规范工作符合预期。我已经参考了多个来源,以确定可能的原因,但无法确定。我错过了什么或做错了什么Java 规范对象没有';即使在创建之后也不包含任何条件,java,spring-boot,spring-data-jpa,Java,Spring Boot,Spring Data Jpa,在Spring数据JPA中创建动态搜索规范时面临问题 当我将源-目标或dispatchNumber值传递给下面实现的规范时,返回的规范对象不包含任何条件(请参阅)。然而,第三方和自始至终的规范工作符合预期。我已经参考了多个来源,以确定可能的原因,但无法确定。我错过了什么或做错了什么 存储库 规格 公共最终类规范{ 私有TripSearchSpecification(){} 公共静态规范noFilter(){ 返回规范。其中(空); } 公共静态规范searchByFromDateToDate(L
公共最终类规范{
私有TripSearchSpecification(){}
公共静态规范noFilter(){
返回规范。其中(空);
}
公共静态规范searchByFromDateToDate(LocalDate fromDate,LocalDate toDate){
返回新规范(){
@凌驾
公共谓词toPredicate(根根、CriteriaQuery查询、CriteriaBuilder CriteriaBuilder){
列表谓词列表=新的ArrayList();
add(criteriaBuilder.greaterThanOrEqualTo(root.get(“tripDate”),fromDate));
add(criteriaBuilder.lessThanOrEqualTo(root.get(“tripDate”),toDate));
返回criteriaBuilder.and(predicateList.toArray(新谓词[0]);
}
};
}
公共静态规范searchByParty(Party){
返回新规范(){
@凌驾
公共谓词toPredicate(根根、CriteriaQuery查询、CriteriaBuilder CriteriaBuilder){
返回criteriaBuilder.equal(root.get(“party”),party);
}
};
}
公共静态规范searchByDispatchNumber(字符串dispatchNumber){
返回新规范(){
@凌驾
公共谓词toPredicate(根根、CriteriaQuery查询、CriteriaBuilder CriteriaBuilder){
返回criteriaBuilder.equal(root.get(“dispatchNumber”)、dispatchNumber);
}
};
}
公共静态规范searchBySourceDestination(位置源、位置目标){
返回新规范(){
@凌驾
公共谓词toPredicate(根根、CriteriaQuery查询、CriteriaBuilder CriteriaBuilder){
列表谓词列表=新的ArrayList();
add(criteriaBuilder.equal(root.get(“source”),source));
add(criteriaBuilder.equal(root.get(“destination”),destination));
返回criteriaBuilder.and(predicateList.toArray(新谓词[0]);
}
};
}
}
您可以使用编写查询模板来实现动态搜索
根据调用方法时的参数,在执行之前,查询模板将内置到不同的查询字符串中。在last if语句中(
TripServiceImpl\searchTrips
),而不是tripSpecification。和(另一个规范)
必须是tripSpecification=tripSpecification.and(另一种规格)
感谢alex指出了这样一个愚蠢的错误!
@Repository("tripRepository")
public interface TripRepository extends JpaRepository<Trip, Integer>, JpaSpecificationExecutor<Trip> {
}
@Service
public class TripServiceImpl implements TripService {
@Autowired
TripRepository repository;
/*other methods*/
@Override
public List<Trip> searchTrips(LocalDate fromDate, LocalDate toDate, Location source, Location destination,
Party party, String dispatchNumber, Vehicle vehicle) {
Specification<Trip> tripSpecification = TripSearchSpecification.noFilter();
if (fromDate != null && toDate != null && toDate.isAfter(fromDate)) {
tripSpecification = tripSpecification.and(TripSearchSpecification.searchByFromDateToDate(fromDate, toDate));
}
if (party.getParty_id() != 0) {
tripSpecification = tripSpecification.and(TripSearchSpecification.searchByParty(party));
}
if (!StringUtils.isEmpty(dispatchNumber)) {
tripSpecification.and(TripSearchSpecification.searchByDispatchNumber(dispatchNumber));
}
if (source.getLocation_id() != 0 && destination.getLocation_id() != 0) {
tripSpecification.and(TripSearchSpecification.searchBySourceDestination(source, destination));
}
final List<Trip> tripList = repository.findAll(tripSpecification);
return tripList;
}
}
@Controller
public class TripController {
@Autowired
TripService tripService;
/*other methods*/
@GetMapping("/trip/search")
public String searchTrips(@ModelAttribute("searchTrip") Trip filter,
@RequestParam(required = false, value = "fromDate") @DateTimeFormat(pattern = "dd/MM/yyyy") LocalDate fromDate,
@RequestParam(required = false, value = "toDate") @DateTimeFormat(pattern = "dd/MM/yyyy") LocalDate toDate,
RedirectAttributes redirectAttributes, HttpServletRequest request) {
List<Trip> trips = tripService.searchTrips(fromDate, toDate, filter.getSource(), filter.getDestination(),
filter.getParty(), filter.getDispatchNumber(), filter.getVehicle());
if (!trips.isEmpty()) {
redirectAttributes.addFlashAttribute("tripList", trips);
} else {
String message = messageSource.getMessage("search.output.failure", new String[]{null},
request.getLocale());
redirectAttributes.addFlashAttribute("error", message);
}
return "redirect:/trip";
}
}
@Entity
@Table(name = "trip")
public class Trip {
@Id
@Column(name = "trip_id")
private int tripId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "party_id")
private Party party;
@DateTimeFormat(pattern = "dd/MM/yyyy")
@Column(name = "trip_date")
private LocalDate tripDate;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "src_id")
private Location source;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "dest_id")
private Location destination;
@Column(name = "dispatch_no")
private String dispatchNumber;
/*few other fields*/
/*default and parameterized constructor*/
/*getters and setters*/
}
public final class TripSearchSpecification {
private TripSearchSpecification() { }
public static Specification<Trip> noFilter() {
return Specification.where(null);
}
public static Specification<Trip> searchByFromDateToDate(LocalDate fromDate, LocalDate toDate) {
return new Specification<Trip>() {
@Override
public Predicate toPredicate(Root<Trip> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicateList = new ArrayList<>();
predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("tripDate"),fromDate));
predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("tripDate"),toDate));
return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
}
};
}
public static Specification<Trip> searchByParty(Party party) {
return new Specification<Trip>() {
@Override
public Predicate toPredicate(Root<Trip> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.equal(root.get("party"), party);
}
};
}
public static Specification<Trip> searchByDispatchNumber(String dispatchNumber) {
return new Specification<Trip>() {
@Override
public Predicate toPredicate(Root<Trip> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.equal(root.get("dispatchNumber"), dispatchNumber);
}
};
}
public static Specification<Trip> searchBySourceDestination(Location source, Location destination) {
return new Specification<Trip>() {
@Override
public Predicate toPredicate(Root<Trip> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicateList = new ArrayList<>();
predicateList.add(criteriaBuilder.equal(root.get("source"),source));
predicateList.add(criteriaBuilder.equal(root.get("destination"),destination));
return criteriaBuilder.and(predicateList.toArray(new Predicate[0]));
}
};
}
}