繁体   English   中英

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

[英]how to filter a left join in jpa query

我在无法返回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)

如果addressBook有一行,它会addressBook 但是,如果删除所有地址,我将无法获得任何结果。

我想要在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)

注意,我发现DISTINCT很重要,否则我得到了重复的数据(在您的情况下为客户)。

另外,返回的具有地址的客户将不会返回该客户的所有地址。 附加列表将仅具有markForDelete false的地址。

我得出的结论是,对于JPA来说,这是不可能的。 即使使用特定于Hibernate的@Where注释, @Where也很难。

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

  1. 使用特定于Hibernate的@Where(clause =“ markForDelete <>'1')注释relationship ,而不是相关实体。

  2. 不要使用left join fetch因为即使在带注释的情况下,它似乎也会忽略其他条件。

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

我想使用软删除对我来说几乎无法使用提取连接...我真的发现JPA和Hibernate有时令人沮丧,无法使用。

有趣的是,根据此页面,EclipseLink似乎支持软删除: https : //wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM