1

我正在尝试在 QueryDSL(JPA、Hibernate 提供程序、Oracle 数据库)中转换以下 SQL 查询:

select c.id
      , c.name
      , count(coalesce(s.company_id_source, t.company_id_target))
  from company              c
  left join company_mapping s on(s.company_id_source = c.id)
  left join company_mapping t on(t.company_id_target = c.id)
 group 
    by c.id
      ,c.name;

我的java代码:

QCompany company = new QCompany("company");
QCompanyMapping companyMappingSource = new QCompanyMapping("companymappingS");
QCompanyMapping companyMappingTarget = new QCompanyMapping("companymappingT");
JPAQuery query = new JPAQuery(entityManager);
query = query.from(company)
query = query.leftJoin(company.companyMappingsForCompanyIdSource, companyMappingSource);
query = query.leftJoin(company.companyMappingsForCompanyIdTarget, companyMappingTarget);
List<Expression<?>> outPaths = new ArrayList<Expression<?>>();
// add c.id and c.name to outPaths - omitted
outPaths.add(companyMappingSource.companyByCompanyIdSource.count().add(companyMappingTarget.companyByCompanyIdTarget.count()));
// add the group by clause - omitted
List<Object[]> rows = query.listDistinct( outPaths.toArray(new Expression<?>[0]));

它编译得很好,但我得到一个运行时异常

ORA-00904: "COMPANY0_"."ID": 标识符无效

这是根据 Hibernate 日志输出生成的查询:

select distinct company0_.ID as col_0_0_, company0_.NAME as col_1_0_, 
count(companymap1_.COMPANY_ID_SOURCE)+count(companymap2_.COMPANY_ID_TARGET) as col_2_0_
from COMPANY company0_ 
left outer join COMPANY_MAPPING companymap1_ on company0_.ID=companymap1_.COMPANY_ID_SOURCE
, COMPANY company3_
left outer join COMPANY_MAPPING companymap2_ on company0_.ID=companymap2_.COMPANY_ID_TARGET
, COMPANY company4_ 
where companymap1_.COMPANY_ID_SOURCE=company3_.ID and companymap2_.COMPANY_ID_TARGET=company4_.ID 
group by company0_.ID , company0_.NAME

如果我在 Oracle 中手动运行这个查询,我会得到同样的错误。我不明白与公司(company3_ 和 company4_)的两个无用连接来自何处以及整个 where 子句。如果我删除这些部分,它会再次在 Oracle 中工作。

在查询 obj 输出上调用 toString()

select company
from Company company
  left join company.companyMappingsForCompanyIdSource as companymappingS
  left join company.companyMappingsForCompanyIdTarget as companymappingT
where upper(company.name) like ?1 escape '!'
group by company.id, company.name

QCompanyMapping 类定义为

public class QCompanyMapping extends EntityPathBase<CompanyMapping> {
// ..
    public final QCompany companyByCompanyIdSource;

    public final QCompany companyByCompanyIdTarget;
// ..
}

可能的替代解决方案? 有一个替代的等效 SQL 查询似乎更优雅,并且可以通过 Hibernate 正确翻译:

select c.id
,      c.name
,      count(cm.id)
from   company c
left join company_mapping cm on c.id in (cm.company_id_source, cm.company_id_target)
group by c.id, c.name

但是我不知道如何在 QueryDSL 中表达它。

4

2 回答 2

1

您应该在连接后使用别名路径。

这些可能会触发其他连接

outPaths.add(QCompanyMapping.companyMapping.companyByCompanyIdSource.count().add(
         QCompanyMapping.companyMapping.companyByCompanyIdTarget.count()));
于 2013-05-16T10:55:35.853 回答
1

如果我改变

  1. “companyMappingSource.companyByCompanyIdSource.count()”到“companyMappingSource.count()”
  2. “companyMappingTarget.companyByCompanyIdTarget.count()”到“companyMappingTarget.count()”

在您的Java代码中进行第一次查询,然后它可以工作:

outPaths.add(companyMappingSource.count().add(companyMappingTarget.count()));
于 2013-05-24T09:25:45.900 回答