如何在jpa查询中过滤左连接

如何在jpa查询中过滤左连接,jpa,Jpa,我遇到问题,无法返回JPA对象。我有客户和地址,客户可以有零个或多个地址。我还软删除项目。此查询有效,除非没有返回地址,否则我无法返回客户详细信息(返回null) 因此,我将我的查询设置为: select c from Customer c left join fetch c.createUser left join fetch c.lastUpdateUser left join fetch c.addressBook a where c.id = 1 and c.markForDele

我遇到问题,无法返回
JPA
对象。我有客户和地址,客户可以有零个或多个地址。我还软删除项目。此查询有效,除非没有返回地址,否则我无法返回客户详细信息(返回
null

因此,我将我的查询设置为:

select c from Customer c
left join fetch c.createUser 
left join fetch c.lastUpdateUser 
left join fetch c.addressBook a 
where c.id = 1 and c.markForDelete = false 
and (a.id is null or a.markForDelete = false)
如果
地址簿中有一行,则可以正常工作。但是如果我删除所有的地址,我就不会得到任何结果

我试图在SQL中实现的等效功能是:

select * from customers c
left join customer_addresses ca
on c.id = ca.customer_id
and c.markForDelete = 0
and ca.markForDelete = 0;

它可以工作并给出一个结果。

好的,在这里使用类似的数据,我发现以下查询应该满足您的要求:

SELECT DISTINCT c FROM Customer c
LEFT JOIN FETCH c.createUser
LEFT JOIN FETCH c.lastUpdateUser
LEFT JOIN FETCH c.addressBook a
WHERE c.id = 1 AND c.markForDelete = false
AND (SIZE(c.addressBook) = 0 OR a.markForDelete = false)
注意,我发现
不同的
很重要,否则我会得到重复的数据(您的客户)


此外,返回的具有地址的客户不会返回该客户的所有地址。附件中的地址只有
markForDelete
false。

我得出结论,JPA不可能做到这一点。即使使用特定于Hibernate的
@Where
注释,也很困难

我发现做我想做的事情的唯一方法是,非常简单的“软删除”项目的情况是:

  • 用Hibernate-specific@Where(clause=“markForDelete'1')注释
    关系,而不是相关实体

  • 不要使用
    left join fetch
    ,因为它似乎忽略了附加条件,即使对其进行了注释

  • 而是使用标准联接,然后从事务中访问属性以触发子查询

  • 我猜使用软删除几乎使fetch连接对我来说不可用……我真的觉得JPA和Hibernate有时太令人沮丧了


    有趣的是,根据这个页面,EclipseLink似乎支持软删除:

    如果将最后一个子句更改为
    和(a为null或a.markForDelete=false)
    ?或者,您可以尝试
    和(SIZE(c.addressBook)=0或a.markForDelete=false)
    。我在Hibernate/JPA中尝试了这两种方法,但在没有地址的情况下仍然没有得到任何结果。有时我想知道直接编写SQL是否会更容易!这是一项2分钟的工作……有趣……我尝试了类似的方法,它对我有效。也许我会将大小改为(a为null或a.markfordelite=0)。