querydsl在子查询中使用父查询实体路径

时间:2014-11-29 15:37:32

标签: subquery querydsl

我试图在querydsl中表示以下查询:

select a1.agreement_id, ad1.agreement_detail_id
from agreement a1
  inner join agreement_details ad1 on a1.agreement_id=ad1.agreement_id 
where ad1.transaction_id in (
  select max(ad2.transaction_id) 
  from agreement_details ad2 
    inner join agreement a2 on ad2.agreement_id=a2.agreement_id 
  where 
    ad2.transaction_id<=1234
    and a2.agreement_id=a1.agreement_id 
    and a2.entity_split_id=5678 
) 
order by a1.agreement_id asc

但是,我无法让querydsl在子查询的where子句中使用父查询中的表。例如,如果我编写如下代码:

QAgreement a1 = QAgreement.agreement;
QAgreementDetails ad1 = QAgreementDetails.agreementDetails;
QAgreement a2 = QAgreement.agreement;
QAgreementDetails ad2 = QAgreementDetails.agreementDetails;
HibernateQuery query = getHibernateQuery();
query.from(a1)
    .innerJoin(a1.agreementDetailsesByAgreementId, ad1)
    .fetch()
    .where(ad1.transactionId.in(
      new JPASubQuery().from(ad2)
        .innerJoin(ad2.agreementByAgreementId, a2)
        .where(ad2.transactionId.loe(maxTransactionId))
        .where(a1.agreementId.eq(a2.agreementId))
        .where(a2.entitySplitByEntitySplitId.entitySplitId.eq(entitySplitId))
        .list(ad2.transactionId.max())))
        .orderBy(a1.agreementId.asc());

并执行它,生成的SQL看起来像

select  -- Some columns removed for brevity
   agreement0_.agreement_id as agreemen1_0_0_,
   agreementd1_.agreement_detail_id as agreemen1_11_1_ 
from
   agreement agreement0_ 
inner join
   agreement_details agreementd1_ 
       on agreement0_.agreement_id=agreementd1_.agreement_id 
where
   agreementd1_.transaction_id in (
       select
           max(agreementd2_.transaction_id) 
       from
           agreement_details agreementd2_ 
       inner join
           agreement agreement3_ 
               on agreementd2_.agreement_id=agreement3_.agreement_id 
       where
           agreementd2_.transaction_id<=1234
           and agreement3_.agreement_id=agreement3_.agreement_id 
           and agreement3_.entity_split_id=5678 
   ) 
order by
   agreement0_.agreement_id asc

您可以看到协议实体路径a1的别名未在子查询中使用,并且正在被协议实体路径a2的别名替换。在querydsl中还有什么我需要做的才能生成这个查询吗?

1 个答案:

答案 0 :(得分:1)

问题在于您不使用唯一变量

QAgreement a1 = QAgreement.agreement;
QAgreementDetails ad1 = QAgreementDetails.agreementDetails;
QAgreement a2 = QAgreement.agreement;
QAgreementDetails ad2 = QAgreementDetails.agreementDetails;

在这种情况下,a1和a2以及ad1和ad2指的是相同的路径。

Java代码中的变量名无关紧要,您需要使用它们,例如像

QAgreement a1 = new QAgreement("a1");
QAgreementDetails ad1 = new QAgreementDetails("ad1");
QAgreement a2 = new QAgreement("a2");
QAgreementDetails ad2 = new QAgreementDetails("ad2");