我遇到了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
中有一行,它会正常工作。但是,如果我删除所有地址,我将无法获得结果。
我在SQL中尝试完成的相当于:
select * from customers c
left join customer_addresses ca
on c.id = ca.customer_id
and c.markForDelete = 0
and ca.markForDelete = 0;
有效并给我一个结果。
答案 0 :(得分: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的地址。
答案 1 :(得分:0)
我得出的结论是,JPA不可能实现这一点。即使使用Hibernate特定的@Where
注释,它也很难。
我发现做我想要的唯一方法是“软删除”项目非常直接的情况,是:
使用特定于Hibernate的@Where(clause =“markForDelete<>'1')注释relationship
,而不是相关实体
请勿使用left join fetch
因为它似乎会忽略其他标准,即使它已注释。
而是使用标准连接,然后从事务中访问属性以触发子查询。
我想使用软删除几乎使得fetch连接对我来说无法使用...我真的觉得JPA和Hibernate有时很难用。
有趣的是,根据此页面,EclipseLink似乎支持软删除:https://wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete