首页 > 解决方案 > 使用 listJoin 规范时错误的总元素

问题描述

我正在使用 JPA CriteriaBuilder 和规范来过滤数据。

这只是一个说明性示例

我有 3 张桌子(司机汽车类型)。一个司机可以开很多辆车,每辆车都有一个类型。

我列出了具有服务器端分页和详细搜索功能的驱动程序。

我正在尝试按类型列表获取驱动程序。我的问题是,当驾驶员拥有不止一辆车时,我得到的 totalElements 是sum(driver+numberOfCars),它大于驾驶员的数量。

驱动程序.java

@Entity
public class Driver implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, mappedBy="driver",orphanRemoval = true)
    @JsonIgnoreProperties("driver")
    private List<Car> cars;

    //Getters and setters
}

汽车.java

@Entity
public class Car implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH})
    private Type type;

    @ManyToOne(fetch = FetchType.LAZY)
    private Driver driver;

    //Getters and setters
}

类型.java

@Entity
public class Type implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.REFRESH})
    private String name;

    private Integer age;

    //Getters and setters
}

DriverSpecification.java

@Component
public class EprestationSpecification extends BaseSpecification<Driver, String, Filter> {

    @Override
    public Specification<Driver> SearchByTerm(String request) {
        return null;
    }

    @Override
    public Specification<Driver> getFilter(CustomFilterDTO filter) {
        return (root, query, cb) -> {
            ListJoin<Driver, Car> driverCarListJoin = root.joinList("cars", JoinType.INNER);
            if(filter.getTypes().length > 0){
                return cb.in(driverCarListJoin.get("type")).value(Arrays.asList(filter.getTypes())));
            }
            return null;
        }
    }
}

DriverController.java

@PostMapping("/pageFilter")
public ResponseEntity<Page<EPrestationList>> findPaginatedByFilter(@RequestBody CustomFilter filter) {
    try {
        Pageable pageable = null;
        if(filter.getPageable().getSort().getOrder().equals("desc")){
            pageable = PageRequest.of(filter.getPageable().getPageNumber(), filter.getPageable().getPageSize(), Sort.by(Sort.Order.desc(filter.getPageable().getSort().getSort())));
        }
        else{
            pageable = PageRequest.of(filter.getPageable().getPageNumber(), filter.getPageable().getPageSize(), Sort.by(Sort.Order.asc(filter.getPageable().getSort().getSort())));
        }

        Page<Driver> resultPage = driverRepository.findAll(driverSpecification.getFilter(filter),pageable);

        System.out.println(resultPage.getTotalElements()); //the total number is wrong

        return new ResponseEntity<>(newResultPage, HttpStatus.OK);
    } catch (DataAccessException e) {
        System.out.println("DataAccessException : "+e);
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }
}

标签: angularspring-bootspring-data-jpa

解决方案


推荐阅读