[英]JPA Soft Delete Repository + Auditing
我需要实现 JPA 软删除存储库并同时支持 JPA 审计多个列。 目前,我已经通过 EL 和 @Query+@Modifying 注释实现了软删除存储库:
@Override
@Modifying
@Query("update #{#entityName} e set e.active = false where e.id = ?1")
void deleteById(UUID id);
@Override
default void delete(T entity)
{
deleteById(entity.getId());
}
@Override
@Modifying
@Query("update #{#entityName} e set e.active = false where e.id in ?1")
void deleteAll(Iterable<? extends T> iterable);
@Override
@Modifying
@Query("update #{#entityName} e set e.active = false")
void deleteAll();
但是对于这样的实现,审计列不会更新,因为如果我正确理解, @Query
注释不会触发任何生命周期回调方法。
@Where
实体级别的注释不是一个选项,因为需要有可能查询软删除的实体。
您能否提供任何其他可能的解决方案?
如果您使用的是 Hibernate,那么您可以自定义在删除时执行的 SQL,这样就不会发出删除语句,而是将活动标志设置为 false。 在这种情况下,您将调用EntityManager#remove
(通过 Spring 数据的存储库抽象),然后生命周期侦听器将按预期执行。
@SQLDelete(sql = "UPDATE someEntity SET active= 0 WHERE id = ?",
check ResultCheckStyle.COUNT)
@Entity
public class SomeEntity{
//if SomeChildEntity has similar @SqlDelete clause then would be 'deleted' also
@OneToMany(cascade = CascadeType.REMOVE)
private Set<SomeChildEntity> children;
}
这具有额外的优势,即级联删除也应该按预期执行,而在使用批量删除时它们不会。
更新:我决定 go 使用覆盖的默认删除存储库方法将活动标志更新为“false”并通过常见的save()
方法保存实体。
@Override
default void deleteById(UUID id)
{
Assert.notNull(id, "The given id must not be null!");
Optional<T> entity = this.findById(id);
entity.ifPresent(this::delete);
}
@Override
default void delete(T entity)
{
Assert.notNull(entity, "The entity must not be null!");
entity.setActive(Boolean.FALSE);
this.save(entity);
}
@Override
default void deleteAll(Iterable<? extends T> entities)
{
Assert.notNull(entities, "The given Iterable of entities must not be null!");
for (T entity : entities)
{
this.delete(entity);
}
}
@Override
default void deleteAll()
{
for (T element : this.findAll())
{
this.delete(element);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.