我正在尝试在 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 中表达它。