繁体   English   中英

如何使用Spring Boot和JPA一起软性删除父级和子级(级联)

[英]How to soft delete parent and child together (cascade) using spring boot with jpa

我有一个不允许删除记录的项目。 相反,我们通过更新db在所有实体中都通用的column(deleteFlag)来软删除它们。 我正在尝试以通用方式使用JPA来实现这一目标,如果可能的话,我想要一个JPA解决方案。 deleteFlag是设置为Y或N的软删除标志。

我到目前为止编写的代码:

所有实体扩展的基类:

@MappedSuperclass
public class BaseEntity implements Serializable {

private static final long serialVersionUID = 1L;

@Column(name = "CREATED_BY_C")
private String createdByC;

@Column(name = "CREATED_DATE_DT", updatable = false, insertable = false)
private Timestamp createdDateDt;

@Column(name = "UPDATE_DATE_DT", updatable = false, insertable = false)
private Timestamp updateDateDt;

@Column(name = "UPDATED_BY_C")
private String updatedByC;

@Column(name = "DELETE_FLG")
private String deleteFlag;
//getters and setters

所有CrudRepos扩展的BaseRepo:

    @NoRepositoryBean
    public interface BaseCrudRepository<T extends BaseEntity, ID extends Serializable>, CrudRepository<T, ID> {


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

    //Look up deleted entities
    @Query("select e from #{#entityName} e where e.deleteFlag ='Y'")
    public List<T> recycleBin(); 

    //Soft delete.
    @Query("update #{#entityName} e set e.deleteFlag='Y' where e.id=:id")
    @Modifying
    @Transactional
    public void softDelete(@Param("id")Integer id);     
}

我要进行软删除的示例实体:

@Entity
@Table(name = "SOME_PARENT_TABLE", schema = "SOME_SCHEMA")
public class SomeParentTable extends BaseEntity {
private static final long serialVersionUID = 1L;

@Id
@Column(name = "id_field")
private Integer someParentTableId;

//more fields here

//bi-directional many-to-one association to SomeChildTable
@OneToMany(mappedBy = "sdIncomingTransaction", , cascade=CascadeType.ALL)
private List<SomeChildTable> someChildTables;

所以当我这样做时:

someParentTableRepository.softDelete(someParentTableId);

只有someParentTable的deleteflag标记为Y。但是,我希望将与其关联的所有SomeChildTable也都进行软删除。

有没有办法做到这一点? 我正在使用spring数据jpa。 如果需要,请随时询问更多详细信息。

不传播软删除,因为它不是默认的存储库方法之一。 您可以在此处检查界面:

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html

所以JPA不会传播它,因为它是一种奇怪的方法,它不是接口的一部分,而Spring对此一无所知。 这就是为什么即使全部级联也不会传播的原因。 您应该重写delete()方法,并使其进行软删除以符合该接口。

@Override
@Query("update #{#entityName} e set e.deleteFlag='Y' where e.id=:id")
@Modifying
@Transactional
public void delete(@Param("id")Integer id);     

如果需要,则添加硬删除方法;)这是更好的解决方案,因为delete()是应在代码中调用的默认方法,并且应具有默认行为。 否则,人们会在代码中的某些地方按习惯而不是softDelete()编写delete(),这样您就会遇到问题。

还有一个注释,它在实体类上与休眠一起使用。

@SQLDelete(sql = “UPDATE table SET deleteFlag= ‘Y’ WHERE id = ?”)

我不确定确切的语法,但它会覆盖默认的删除。 我不确定这是Spring JPA的一部分

暂无
暂无

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

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