在JPA Criteria中使用相同的表两次

时间:2014-09-10 16:42:25

标签: java sql jpa criteria-api

我有这个SQL查询:

SELECT lf.load_factor, ls.load_incidences, avg(lsa.accumulated_load_incidences)
FROM load_factor lf
INNER JOIN load_spectrum ls ON (lf.load_factor_id = ls.load_factor_id)
INNER JOIN load_spectrum_aircraft_history lsa ON (lf.load_factor_id = lsa.load_factor_id)
INNER JOIN flight f ON (lsa.flight_id = f.flight_id)
INNER JOIN aircraft a ON (f.aircraft_id = a.aircraft_id)
WHERE a.aircraft_id = X
GROUP BY (lf.load_factor_id)
HAVING count(lf.load_factor_id) > 1;

在Where子句中,“X”是变量。所以,X可以假设任何数字。

我尝试使用JPA Criteria执行相同的查询。

所以我写了这段代码:

// Criteria Builder

    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);

// ROOT
    Root<LoadSpectrumAircraftHistory> loadSpectrumAircraftRoot = query.from(LoadSpectrumAircraftHistory.class);
    Root<LoadSpectrum> loadSpectrumRoot = query.from(LoadSpectrum.class);

// JOIN Declarations
    Join<LoadSpectrumAircraftHistory, LoadFactor> loadFactor = loadSpectrumAircraftRoot.join("loadFactor");
    Join<LoadSpectrum, LoadFactor> loadSpectrum = loadSpectrumRoot.join("loadFactor");
    Join<LoadSpectrumAircraftHistory, Flight> flight = loadSpectrumAircraftRoot.join("flight");
    Join<Flight, Aircraft> aircraft = flight.join("aircraft");


// Expressions for SELECT clause
    Expression<Double> loadFactorExp = loadFactor.get("loadFactor");
    Expression<Double> loadIncidences = loadSpectrumRoot.get("loadIncidences");
    Expression<Double> accumulatedLoadIncidences = loadSpectrumAircraftRoot.get("accumulatedLoadIncidences");
    Expression<Double> avg = cb.avg(accumulatedLoadIncidences);

// Predicates for WHERE clause
    Predicate whereClause = cb.equal(aircraft.get("id"), aircraftId);

// Predicates for HAVING clause
    Predicate havingClause = cb.gt(cb.count(loadSpectrumAircraftRoot), 1);

    query.multiselect(loadFactorExp, loadIncidences, avg)
    .where(whereClause)
    .groupBy(loadFactor.get("loadFactorId"))
    .having(havingClause);

    TypedQuery<Object[]> qry = entityManager.createQuery(query);

但是,遗憾的是,此代码不会像我预期的那样生成SQL查询。 下面是我的JPA代码生成的SQL查询:

select loadfactor2_.load_factor as col_0_0_, loadspectr1_.load_incidences as col_1_0_, avg(loadspectr0_.accumulated_load_incidences) as col_2_0_ 
from load_spectrum_aircraft_history loadspectr0_ 
inner join load_factor loadfactor2_ on loadspectr0_.load_factor_id=loadfactor2_.load_factor_id 
inner join flight flight3_ on loadspectr0_.flight_id=flight3_.flight_id 
inner join aircraft aircraft4_ on flight3_.aircraft_id=aircraft4_.aircraft_id 
cross join load_spectrum loadspectr1_ inner join load_factor loadfactor5_ on loadspectr1_.load_factor_id=loadfactor5_.load_factor_id 
where aircraft4_.aircraft_id=1 
group by loadfactor2_.load_factor_id 
having count(*)>1

如您所见,LoadSpectrum和LoadFactor之间的连接与新的Load Factor(loadfactor5_)相关,而不是LoadSpectrumAircraftHistory和LoadFactor(loadfactor2 _)之间的连接中使用的相同Load Factor。

它们是不同的表,因此这些连接的因子ID不相同。

如何使用同一个表(loadfactor2 _)??

*请原谅我的英文

0 个答案:

没有答案