我遇到了问题。我运行春靴3。它在春靴2中工作,我有这样的关系(简化的情况下的问题)
组具有用户。用户具有令牌。
@Entity(name = "Group")
@Where(clause = "not is_deleted or is_deleted is null")
@SQLDelete(sql = "UPDATE group SET is_deleted = true, updated_at = NOW() WHERE id=?")
class GroupEntity(
@OneToMany(mappedBy = "group", cascade = [CascadeType.ALL], fetch = FetchType.EAGER)
val users: MutableSet<UserEntity> = HashSet()
@Entity(name = "User")
@Where(clause = "not is_deleted or is_deleted is null")
@SQLDelete(sql = "UPDATE user SET is_deleted = true, updated_at = NOW() WHERE id=?")
class UserEntity(
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "group_id", nullable = true)
val group: GroupEntity,
@OneToOne(cascade = [CascadeType.ALL], mappedBy = "user", fetch = FetchType.EAGER)
var token: TokenEntity?
@Entity(name = "Token")
@Where(clause = "not is_deleted or is_deleted is null")
@SQLDelete(sql = "UPDATE token SET is_deleted = true, updated_at = NOW() WHERE id=?")
class TokenEntity(
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id", nullable = true)
val user: UserEntity
现在我有一个测试来检查我是否可以删除用户。作为这个测试的一部分,我想使用标准的JpaRepository. findById获取一个只有一个已删除用户的组。然而,这总是会给出结果:
NotFoundException(detail=Group with id 9aee9ef0-ac33-11ec-b909-0242ac120002 not found, throwable=null)
即使它确实存在于测试数据库中。我已经启用了hibsql调试选项,并发现结果查询如下:
select * from group f1_0
left join user v1_0 on f1_0.id=v1_0.group_id
left join token t1_0 on v1_0.id=t1_0.user_id where
(not v1_0.is_deleted or v1_0.is_deleted is null)
and f1_0.id='9aee9ef0-ac33-11ec-b909-0242ac120002'
and (not f1_0.is_deleted or f1_0.is_deleted is null)
我希望得到一个包含空用户集的grup实体(因为它们都被删除了)。但是这一行-
(not v1_0.is_deleted or v1_0.is_deleted is null)
放在where子句中会产生完全不同的行为--如果删除了组中的所有用户,它将不返回任何内容。我所期望和想要的是以下查询:
select * from group f1_0
left join user v1_0 on f1_0.id=v1_0.group_id and
(not v1_0.is_deleted or v1_0.is_deleted is null)
left join token t1_0 on v1_0.id=t1_0.user_id where
f1_0.id='9aee9ef0-ac33-11ec-b909-0242ac120002'
and (not f1_0.is_deleted or f1_0.is_deleted is null)
把user的is deleted部分移到一个连接子句中,我只是不知道如何让hib做到这一点
2条答案
按热度按时间gopyfrb31#
发帖后,我尝试了另一件事:将@Fetch(FetchMode.SELECT)添加到用户集合中可以使它工作,但是我仍然对这个解决方案不满意,我担心它不能像我期望的那样开箱即用,并且我可能在其他地方/情况下遇到类似的问题,我可能没有测试
nimxete22#
请看下面文章的第4节:https://www.baeldung.com/spring-jpa-soft-delete。它告诉您不要使用
@Where
,如果要查询软删除的数据,请使用@SQLDelete
、@FilterDef
和@Filter
。然后,在使用资料档案库之前,将过滤器应用于实体管理器的会话。完成后,请记住禁用过滤器。