按提取连接属性排序

时间:2014-07-23 10:34:41

标签: java hibernate jpa-2.0

我有一个criteriaQuery

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<School> criteriaQuery = builder.createQuery(School.class);
    Root root = criteriaQuery.from(EducationDistrictBundle.class);
    criteriaQuery.distinct(true);
    Join join = root.join("schoolList",JoinType.LEFT);
    join.fetch("address", JoinType.LEFT);
    criteriaQuery.select(join);

添加谓词和排序

 criteriaQuery = criteriaQuery.where(builder.and(predicates.toArray(new Predicate[predicates.size()])));
 criteriaQuery.orderBy(builder.desc(join.get("address").get("fullAddress")));

SQL查询看起来像这样

    SELECT DISTINCT
  school2_.id                              AS id1_52_0_,
  address3_.id                             AS id1_1_1_,
  school2_.createdTs                       AS createdT2_52_0_,
  school2_.guid                            AS guid3_52_0_,
  school2_.updatedTs                       AS updatedT4_52_0_,
  school2_.version                         AS version5_52_0_,
  school2_.accreditation                   AS accredit6_52_0_,
  school2_."address_id"                    AS address14_52_0_,
  school2_."belonging_id"                  AS belongi15_52_0_,
  school2_.director                        AS director7_52_0_,
  school2_."financialType_id"              AS financi16_52_0_,
  school2_.fullName                        AS fullName8_52_0_,
  school2_.license                         AS license9_52_0_,
  school2_.number                          AS number10_52_0_,
  school2_.parent_id                       AS parent_17_52_0_,
  school2_.school                          AS school11_52_0_,
  school2_.shortName                       AS shortNa12_52_0_,
  school2_.site                            AS site13_52_0_,
  school2_."subordinationType_id"          AS subordi18_52_0_,
  school2_."type_id"                       AS type_id19_52_0_,
  address3_.createdTs                      AS createdT2_1_1_,
  address3_.guid                           AS guid3_1_1_,
  address3_.updatedTs                      AS updatedT4_1_1_,
  address3_.version                        AS version5_1_1_,
  address3_.addressUID                     AS addressU6_1_1_,
  address3_.fullAddress                    AS fullAddr7_1_1_,
  address3_.fullHouse                      AS fullHous8_1_1_,
  address3_.houseUID                       AS houseUID9_1_1_,
  address3_.oktmo_id                       AS oktmo_i12_1_1_,
  address3_.plain                          AS plain10_1_1_,
  address3_.postalCode                     AS postalC11_1_1_,
  address3_1_.flat                         AS flat1_0_1_,
  address3_1_.type                         AS type2_0_1_,
  CASE WHEN address3_1_."id" IS NOT NULL THEN 1
  WHEN address3_.id IS NOT NULL THEN 0 END AS clazz_1_
FROM "education_district_bundle" educationd0_ LEFT OUTER JOIN "education_district_bundle_school" schoollist1_
    ON educationd0_.id = schoollist1_."education_district_bundle_id"
  LEFT OUTER JOIN "school" school2_ ON schoollist1_."schoolList_id" = school2_.id
  LEFT OUTER JOIN "address" address3_ ON school2_."address_id" = address3_.id
  LEFT OUTER JOIN "address_refine" address3_1_ ON address3_.id = address3_1_."id"
  CROSS JOIN "address" address4_
WHERE school2_."address_id" = address4_.id AND educationd0_."educationDistrict_id" = 179
ORDER BY address4_.fullAddress DESC

我有一个例外

PSQLException: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list

但为什么会产生交叉连接“address4”?我只想这样订购

ORDER BY address3_.fullAddress DESC

如果我按school.name

订购
order by school2_.shortName asc

学校没有另一个交叉加入...

1 个答案:

答案 0 :(得分:0)

  1. 即使Fetch不是Join类型,也可以进行转换。
  2. 您需要预先定义联接,以避免加入相同的关联两次
  3. 因为你需要为&#34; orderBy&#34;提供这两个额外的连接。您可以使用INNER代替LEFT:

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<School> criteriaQuery = builder.createQuery(School.class);
    Root root = criteriaQuery.from(EducationDistrictBundle.class);
    criteriaQuery.distinct(true);
    Join schoolJoin = root.join("schoolList", JoinType.LEFT);
    Join addressJoin = ((Join) schoolJoin.fetch("address", JoinType.INNER));
    Join fullAddressJoin = addressJoin.fetch("fullAddress", JoinType.INNER);
    criteriaQuery = criteriaQuery.where(builder.and(predicates.toArray(new Predicate[predicates.size()])));
    criteriaQuery.orderBy(builder.desc(fullAddressJoin));
    criteriaQuery.select(schoolJoin);