【发布时间】:2013-05-11 04:28:30
【问题描述】:
我正在尝试在 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 来表达。
【问题讨论】:
-
能否提供Querydsl生成的JPQL查询?错误似乎发生在 JPQL -> SQL 阶段,由 Hibernate 处理
-
您的意思是在查询时调用 toString()?我将输出添加到我编辑的问题中。
-
我不确定是什么失败了,company0_.ID 使用看起来没问题,顺便说一下哪个 Querydsl 版本,还有为什么 JPQL 中的 like 谓词,而 SQL 和 Querydsl 中没有?
-
我使用 QueryDSL 版本 2.9.0。同时我添加了 LIKE 标准,但我也尝试过没有。我正在附加 QCompanyMapping 类中的相关行。