Spring Boot Hibernate @Where软删除实体导致升级到Sping Boot 3后JPA连接出现问题

n3schb8v  于 2023-01-20  发布在  Spring
关注(0)|答案(2)|浏览(152)

我遇到了问题。我运行春靴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做到这一点

gopyfrb3

gopyfrb31#

发帖后,我尝试了另一件事:将@Fetch(FetchMode.SELECT)添加到用户集合中可以使它工作,但是我仍然对这个解决方案不满意,我担心它不能像我期望的那样开箱即用,并且我可能在其他地方/情况下遇到类似的问题,我可能没有测试

nimxete2

nimxete22#

请看下面文章的第4节:https://www.baeldung.com/spring-jpa-soft-delete。它告诉您不要使用@Where,如果要查询软删除的数据,请使用@SQLDelete@FilterDef@Filter。然后,在使用资料档案库之前,将过滤器应用于实体管理器的会话。完成后,请记住禁用过滤器。

相关问题