Java 按获取联接属性排序

Java 按获取联接属性排序,java,hibernate,jpa-2.0,Java,Hibernate,Jpa 2.0,我有一个标准问题 CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<School> criteriaQuery = builder.createQuery(School.class); Root root = criteriaQuery.from(EducationDistrictBundle.class); criteriaQuery.distinct(true);

我有一个标准问题

    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);
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
ORDER BY address3_.fullAddress DESC
我有一个例外

PSQLException: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
但为什么会产生交叉连接“address4”?我只想这样点餐

    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
ORDER BY address3_.fullAddress DESC
如果我是按学校点菜的话

order by school2_.shortName asc
学校没有其他交叉连接

  • 即使Fetch不是联接类型,也可以强制转换它
  • 您需要预先定义联接,以避免两次加入同一关联
  • 由于“orderBy”子句需要这两个附加联接,因此可以使用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);
    
    CriteriaBuilder=em.getCriteriaBuilder();
    CriteriaQuery CriteriaQuery=builder.createQuery(School.class);
    Root=criteriaQuery.from(EducationDistrictBundle.class);
    criteriaQuery.distinct(true);
    Join schoolJoin=root.Join(“schoolList”,JoinType.LEFT);
    Join address Join=((Join)schoolJoin.fetch(“address”,JoinType.INNER));
    Join-fullAddressJoin=addressJoin.fetch(“fullAddress”,JoinType.INNER);
    criteriaQuery=criteriaQuery.where(builder.and(predicates.toArray)(新谓词[predicates.size()));
    orderBy(builder.desc(fullAddressJoin));
    criteriaQuery.select(schoolJoin);
    

  • 然而,这是最干净的解决方案吗?这是我找到的唯一解决方案。请随意研究更好的方法。