Spring Data Rest - 软删除

11

我一直使用Spring Data REST没有遇到任何问题,但现在我有一个要求,当用户对给定实体执行DELETE操作,即DELETE /accounts/<id>时,我需要在数据库上设置一个标志,将该实体标记为已删除,但我仍然希望保留该记录

基本上这意味着我需要在数据库中执行UPDATE而不是DELETE操作。我找不到任何方法来覆盖删除(ID)方法的Spring行为。

一些代码:

@Entity
@Table(name = "account")
public class Account {

    /*
Default value for this field is false but when a receive a 
DELETE request for this entity i want to turn this flag 
to false instead of deleting the record.
    */
    @Column(name = "deleted")
    private boolean deleted;

...
}

账户仓库

@RepositoryRestResource
public interface AccountRepository extends JpaRepository<Account, Integer> {

}

有什么想法吗?


2
请查看我的回答: 使用Spring JPA处理软删除 - 易天明
4个回答

6
尝试创建自定义存储库,以查看其效果。

http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#repositories.custom-implementations

但是删除并不是您需要改变逻辑的唯一地方。我看到了两种处理标志要求的方法:

  1. 在实体定义中添加一个额外的标志,并在删除时更新它。

    在这种情况下,您需要小心,并重写所有现有查询,确保不返回已删除的实体,并记住将来所有实体的结果分离(尽管您可以在低级别上hack SpringData,并自动附加此标志)。

  2. 从原始集合中删除实体,并将其添加到另一个集合中,在该集合中存储实体,直到彻底处理为止。

    在这种情况下,您需要有额外的逻辑来管理处置集合,但这对查询逻辑没有影响。您可以通过向JPA定义添加实体监听器http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#jpa.auditing,与您现有的应用程序集成。


1
谢谢,我能够使用实体中的注释@SoftDelete并遵循Spring教程(http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#repositories.custom-implementations)来完成这个。 - ejoncas
2
你好ejoncas,能否详细说明一下你是如何设置并使用那个注释的呢? - gtiwari333
2
我认为spring-data-common还没有发布@SoftDelete注解。 - prakashpoudel

4

只需要覆盖您的@RepositoryRestResource中的delete方法,就足够了。代码如下:

@RepositoryRestResource
public interface ProductRepository extends PagingAndSortingRepository<Product, Long> {

    @Modifying
    @Query("update Product p set deleted = true where p = :p")
    void delete(Product p);

    @Query("select p FROM Product p WHERE p.deleted = false")
    Page<Product> findAll(Pageable pageable);
}

0
我认为首先你应该使用一个接口来识别只有将使用软删除的实体。之后,您可以覆盖删除方法。如果实体是该接口的实例,则将删除标志设置为true并调用更新,否则调用超级实现。使用SimpleJpaRepository而不是JpaRepository。这里可以找到接口的示例https://github.com/danjee/hibernate-mappings(Persistent和DefaultPersistent)。

0
@Autowired
private AccountRepository accountRepository; 
@Override
   public void accountSoftDelete (Long id) {
        Optional<Account> account1= accountRepository.findById(id);
        account1.get().setDeleted(true);
        accountRepository.save(account1.get());

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接