Объединение нескольких таблиц с помощью построителя критериев и предиката Java - PullRequest
0 голосов
/ 20 мая 2019

У меня есть этот запрос для выполнения с помощью Predicates и CriteriaBuilder в приложении java и eclipselink

SELECT * from exaCar, exaCity, exaGeoLocation,exaMappingLocationCar
where exaCar.id = exaMappingLocationCar.car_id
and exaMappingLocationCar.location_id=exaGeoLocation.id
and exaGeoLocation.parentgeolocation_id=exaCity.location_id
and exaMappingLocationCar.active
and exaCar.active
and exaGeoLocation.active
and exaCity.id=:id_city
and exaCar.status =:Status .....etc

Мне удается выполнить первую часть запроса, но при объединении я заблокирован.

Таблицы автомобиль / геолокация / города / locationCarMapping и в геолокации я должен выбрать все строки с идентификатором ID родителя = город geolocation_ID

код:

 public List<Car> findByFilterAdmin(CarFilterAdmin filter){

    CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
    CriteriaQuery<Car> cq = cb.createQuery(Car.class);
    Root<Car> e = cq.from(Car.class);

    List<Predicate> predicates=setCarFilterAdminPredicate(cb,e,filter);
    if (!predicates.isEmpty()) {
        cq.where(cb.and(predicates.toArray(new Predicate[0])));
    }

    DatabaseUtil.applySort(cb, cq, e, filter.getSort(), filter.getDirection());

    // set list here, we set it in result data with jsonConverter in controller
    return getTypedQueryWithResultList(getEntityManager().createQuery(cq), filter.getPage(), filter.getNbItem())
            .getResultList();
}

public List<Predicate> setCarFilterAdminPredicate(CriteriaBuilder cb, Root<Car> root,CarFilterAdmin filter){
    List<Predicate> predicates=new ArrayList<>();

    if(filter.getId()!=null) {
        predicates.add(cb.equal(root.get("id"), filter.getId()));
    }
    if(StringUtils.isBlank(filter.getIdentification())) {
        predicates.add(cb.equal(root.get(Car.PROP_IDENTIFICATION), filter.getIdentification()));
    }
    if(filter.getActive()!=null) {
        predicates.add(cb.equal(root.get(Car.PROP_ACTIVE), filter.getActive()));
    }
    if(filter.getCarStatus()!=null) {
        predicates.add(cb.equal(root.get(Car.PROP_CAR_STATUS), filter.getCarStatus()));
    }
    if(filter.getCarCategoryId()!=null) {
        predicates.add(cb.equal(root.get(Car.PROP_CAR_TYPE).get("carCategory").get("id"), filter.getCarCategoryId()));
    }
    if(filter.getCarTypeId()!=null) {
        predicates.add(cb.equal(root.get(Car.PROP_CAR_TYPE).get("id"), filter.getCarTypeId()));
    }

    if(filter.getCitId()!=null) {
        predicates.add(cb.equal(root.join(Car_.).join(),filter.getCitId()));
        //predicates.add(cb.equal(root.join("locationCarMapping",JoinType.LEFT).get("id"),root.get("id")));
        //Join<Car,LocationCarMapping> join1=root.join("locationCarMapping",JoinType.LEFT).get("id"),root.get("id");
        //Join<LocationCarMapping, GeoLocation> associate = join1.join(join1,"geoLocation");
        //join1.on(cb.equal(join1.get("id"), root.get("id")));
        //predicates.add(Join)
    }

    return predicates;
}

кроме того, нет двунаправленной связи между объектом класса сущности

this locationCarMapping class

public LocationCarMapping() {
    super();
}

public LocationCarMapping(Long car, Long location) {
    this.car = car;
    this.location = location;
}

//@Column(name = "LOCATION_ID")
@JoinColumn(name = "LOCATION_ID", referencedColumnName = "ID")
private Long location;

//@Column(name = "CAR_ID")
@JoinColumn(name = "CAR_ID", referencedColumnName = "ID")
private Long car;

private Date endDate;

нет ссылки на этот класс в геолокации и в автомобиле

есть идеи? я искал во всех уроках даже на оракуле, но ничего сложного, как вы думаете, возможно ли достичь этого только в одном запросе с предикатами?

...