Java 规范对象没有';即使在创建之后也不包含任何条件

Java 规范对象没有';即使在创建之后也不包含任何条件,java,spring-boot,spring-data-jpa,Java,Spring Boot,Spring Data Jpa,在Spring数据JPA中创建动态搜索规范时面临问题 当我将源-目标或dispatchNumber值传递给下面实现的规范时,返回的规范对象不包含任何条件(请参阅)。然而,第三方和自始至终的规范工作符合预期。我已经参考了多个来源,以确定可能的原因,但无法确定。我错过了什么或做错了什么 存储库 规格 公共最终类规范{ 私有TripSearchSpecification(){} 公共静态规范noFilter(){ 返回规范。其中(空); } 公共静态规范searchByFromDateToDate(L

在Spring数据JPA中创建动态搜索规范时面临问题

当我将源-目标或dispatchNumber值传递给下面实现的规范时,返回的规范对象不包含任何条件(请参阅)。然而,第三方和自始至终的规范工作符合预期。我已经参考了多个来源,以确定可能的原因,但无法确定。我错过了什么或做错了什么

  • 存储库
  • 规格
  • 公共最终类规范{
    私有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]));
                }
            };
        }
    }