简体   繁体   English

在所有实体中使用Hibernate @SQLDelete进行软删除

[英]Using Hibernate @SQLDelete for Soft Delete across All Entities

We have a fairly complex data model and are using Hibernate and Spring Data JPA on top of MySQL. 我们有一个相当复杂的数据模型,并且在MySQL之上使用Hibernate和Spring Data JPA。 We have a base class that all domain objects extend to minimize boiler plate code. 我们有一个基类,所有域对象都扩展到最小化锅炉板代码。 I would like to be able to add soft delete functionality across all of our domain objects using only this class. 我希望能够仅使用此类在所有域对象中添加软删除功能。 However, @SQLDelete requires the table name in the clause: 但是, @SQLDelete需要子句中的表名:

@SQLDelete(sql="UPDATE (table_name) SET deleted = '1' WHERE id = ?")
@Where(clause="deleted <> '1'")

Does anybody know of a way to generalize the SQLDelete statement and allow the extending domain objects to populate their own table names? 有没有人知道如何推广SQLDelete语句并允许扩展域对象填充自己的表名?

If you use hibernate and @SQLDelete , there's no easy solution to your question. 如果你使用hibernate和@SQLDelete ,你的问题就没有简单的解决方案了。 But you can consider another approach to soft delete with Spring Data's expression language: 但您可以考虑使用Spring Data的表达式语言进行软删除的另一种方法:

@Override
@Query("select e from #{#entityName} e where e.deleteFlag=false")
public List<T> findAll();

//recycle bin
@Query("select e from #{#entityName} e where e.deleteFlag=true")
public List<T> recycleBin(); 

@Query("update #{#entityName} e set e.deleteFlag=true where e.id=?1")
@Modifying
public void softDelete(String id); 
//#{#entityName} will be substituted by concrete entity name automatically.

Rewrite base repository like this. 像这样重写基础存储库。 All sub repository interfaces will have soft delete ability. 所有子存储库接口都具有软删除功能。

看看我的答案在这里 ,它描述了如何实现此使用DeleteEventListener

Another approach, which could be more flexible. 另一种方法,可以更灵活。

On Entity level create 在实体级别创建

@MappedSuperclass
public class SoftDeletableEntity {

    public static final String SOFT_DELETED_CLAUSE = "IS_DELETED IS FALSE";

    @Column(name = "is_deleted")
    private boolean isDeleted;
    ...

}

Update your Entity which should be soft deletable 更新您的实体,该实体应该是软删除的

@Entity
@Where(clause = SoftDeletableEntity.SOFT_DELETED_CLAUSE)
@Table(name = "table_name")
public class YourEntity extends SoftDeletableEntity  {...}

Create a custom Interface Repository which extends the Spring's Repository. 创建一个自定义的Interface Repository,它扩展了Spring的Repository。 Add default methods for soft delete. 添加软删除的默认方法。 It should be as a base repo for your Repositories. 它应该是您的存储库的基本仓库。 eg 例如

    @NoRepositoryBean
    public interface YourBaseRepository<T, ID> extends JpaRepository<T, ID> {


        default void softDelete(T entity) {

            Assert.notNull(entity, "The entity must not be null!");
            Assert.isInstanceOf(SoftDeletableEntity.class, entity, "The entity must be soft deletable!");

            ((SoftDeletableEntity)entity).setIsDeleted(true);
            save(entity);
        }

        default void softDeleteById(ID id) {

            Assert.notNull(id, "The given id must not be null!");
            this.softDelete(findById(id).orElseThrow(() -> new EmptyResultDataAccessException(
                    String.format("No %s entity with id %s exists!", "", id), 1)));
        }


    }

NOTE: If your application doesn't have the hard delete then you could add 注意:如果您的应用程序没有硬删除,那么您可以添加

    String HARD_DELETE_NOT_SUPPORTED = "Hard delete is not supported.";

    @Override
    default void deleteById(ID id) {
        throw new UnsupportedOperationException(HARD_DELETE_NOT_SUPPORTED);
    }

    @Override
    default void delete(T entity) {
        throw new UnsupportedOperationException(HARD_DELETE_NOT_SUPPORTED);
    }

    @Override
    default void deleteAll(Iterable<? extends T> entities) {
        throw new UnsupportedOperationException(HARD_DELETE_NOT_SUPPORTED);
    }

    @Override
    default void deleteAll() {
        throw new UnsupportedOperationException(HARD_DELETE_NOT_SUPPORTED);
    }

Hope it could be useful. 希望它可能有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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