【发布时间】:2020-01-14 01:28:27
【问题描述】:
我无法找到使用 JPA/JPQL 实现所需结果的方法,就像我使用此 SQL 查询一样:
select parent.id, child.id, grandchild.id
from salesforce.parent__c parent
left outer join salesforce.child__c child
inner join salesforce.grandchild grandchild on child.grandchild_id__c=grandchild.sfid
and (grandchild.token__c='....')
on parent.sfid=child.parent_id__c
where (parent.external_id__c is not null)
and parent.displayed__c=true
and parent.internal__c=false
and parent.date__c>='....'
and parent.date__c<='....'
order by parent.date__c asc
我正在寻找的查询的目标输出是这样的:
Parent Child Grandchild
P1 null null
P2 null null
P3 C1 GC1
P4 C2 GC2
所有来自父项的记录都符合父项的过滤器,并且子记录不会返回,除非其孙子记录符合 gc 的过滤器。
我对 JPQL 的最佳猜测是这样的
SELECT DISTINCT p FROM Parent p
LEFT JOIN p.childs cl
INNER JOIN cl.grandchilds c
ON c.token__c = '....'
ON cl.parent__c = p.sfid
WHERE p.external_id__c IS NOT NULL
AND p.displayed__c = true
AND p.internal__c = false
AND p.date__c >= '....'
AND p.date__c <= '....'
ORDER BY p.date__c asc
但这是在抛出org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ON
我假设的查询方式还可以:
String queryTxt = "SELECT DISTINCT p FROM Parent p LEFT JOIN p.childs cl INNER JOIN cl.grandchilds c ON c.token__c = '....' ON cl.parent__c = p.sfid WHERE p.external_id__c IS NOT NULL AND p.displayed__c = true AND p.internal__c = false AND p.date__c >= '....' AND p.date__c <= '....' ORDER BY p.date__c asc";
TypedQuery<Parent> typedQuery = entityManager.createQuery(queryTxt, Parent.class);
List<Parent> resultList = typedQuery.getResultList();
如果我尝试使用以下 JPQL,它可以正常执行:
SELECT DISTINCT p FROM Parent p
LEFT JOIN p.childs cl
INNER JOIN cl.grandchilds c
ON c.token__c = '....'
WHERE p.external_id__c IS NOT NULL
AND p.displayed__c = true
AND p.internal__c = false
AND p.date__c >= '....'
AND p.date__c <= '....'
ORDER BY p.date__c asc
但结果不是我想要的,因为子孙之间的内部连接也过滤掉了父记录:
Parent Child Grandchild
P3 C1 GC1
P4 C2 GC2
我还尝试使用帖子开头的 SQL 查询 Query query = entityManager.createNativeQuery(strQuery, Parent.class);,将选择部分替换为 parent.,child.,grandchild.*,但后来我也无法正确解析完整结构:-\
【问题讨论】:
标签: hibernate spring-boot jpa jpql heroku-connect