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

时间:2012-01-05 15:42:48

标签: mysql hibernate spring-data spring-data-jpa

我们有一个相当复杂的数据模型,并且在MySQL之上使用Hibernate和Spring Data JPA。我们有一个基类,所有域对象都扩展到最小化锅炉板代码。我希望能够仅使用此类在所有域对象中添加软删除功能。但是,@SQLDelete需要子句中的表名:

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

有没有人知道如何推广SQLDelete语句并允许扩展域对象填充自己的表名?

3 个答案:

答案 0 :(得分:3)

如果您使用hibernate和@SQLDelete,那么您的问题就不容易解决了。但您可以考虑使用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.

像这样重写基础知识库。所有子存储库接口都具有软删除功能。

答案 1 :(得分:0)

查看我的回答here,其中介绍了如何使用DeleteEventListener

实现此目的

答案 2 :(得分:0)

另一种方法,可能会更灵活。

在实体级别创建

@MappedSuperclass
public class SoftDeletableEntity {

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

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

}

更新您的实体,该实体应该可以软删除

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

创建一个自定义的界面存储库,以扩展Spring的存储库。添加用于软删除的默认方法。它应该作为存储库的基本存储库。例如

    @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)));
        }


    }

注意:如果您的应用程序没有硬删除,则可以添加

    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);
    }

希望它会有用。