【问题标题】:JPA - How to achieve this SQL behaviour (left join parent entity to previously inner joined child & grand child entities)JPA - 如何实现此 SQL 行为(将父实体左连接到先前内部连接的子实体和大子实体)
【发布时间】: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


    【解决方案1】:

    您可以使用FluentJPA 进行任何查询,并使用其Tuple 支持进行投影。向我提供您的实体,我将为您起草完整的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-03
      • 2018-11-13
      • 2010-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      相关资源
      最近更新 更多