繁体   English   中英

JPA 软删除存储库 + 审计

[英]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.

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