2013-05-16 68 views
1

我想在QueryDSL下面的SQL查詢轉換(JPA,Hibernate的供應商,Oracle數據庫):QueryDSL加入生成無效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_)的兩個無用連接是從哪裏來的,而且是從哪裏來的。如果我刪除這些部分,它再次在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查詢,這似乎是更加優雅和可能正確轉換throught休眠:

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。

+0

你能否提供由Querydsl生成的JPQL查詢?這個錯誤似乎發生在JPQL - > SQL階段,由休眠處理 –

+0

你的意思是在查詢時調用toString()?我將輸出添加到我編輯的問題中。 –

+0

我不知道什麼失敗,company0_.ID用法看起來不錯,btw哪些Querydsl版本,也是爲什麼類似謂語在JPQL,但不是在SQL和Querydsl? –

回答

1

如果我改變

  1. 「companyMappingSource.companyByCompanyIdSource.count()」 到 「companyMappingSource.count()」
  2. 「companyMappingTarget.companyByCompanyIdTarget。 count()「改爲」companyMappingTarget.count()「

i ñ你的Java代碼的第一個查詢然後它的工作原理:

outPaths.add(companyMappingSource.count().add(companyMappingTarget.count())); 
+0

是的,就是這樣!生成的查詢看起來很完美,兩個無用的聯接已經消失了! –

1

您應該在連接之後使用別名路徑。

這些可能觸發額外加入

outPaths.add(QCompanyMapping.companyMapping.companyByCompanyIdSource.count().add(
     QCompanyMapping.companyMapping.companyByCompanyIdTarget.count())); 
+0

我將其更改爲outPaths.add(companyMappingSource.companyByCompanyIdSource.count().add(companyMappingTarget.companyByCompanyIdTarget。count()))並編輯我的原始問題,但錯誤仍然 –