简体   繁体   English

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

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

I have a project in which I am not allowed to delete records. 我有一个不允许删除记录的项目。 Instead we soft delete them by updating a column(deleteFlag) in db which is common in all entities. 相反,我们通过更新db在所有实体中都通用的column(deleteFlag)来软删除它们。 I am trying achieve this using JPA in a generic way and I would like a JPA solution if possible. 我正在尝试以通用方式使用JPA来实现这一目标,如果可能的话,我想要一个JPA解决方案。 deleteFlag is the flag to soft delete which is set to Y or N. deleteFlag是设置为Y或N的软删除标志。

Code that I have written so far: 我到目前为止编写的代码:

Baseclass which all entities extend: 所有实体扩展的基类:

@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

BaseRepo which all CrudRepos extend: 所有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);     
}

Sample entity which I am tyring to soft delete: 我要进行软删除的示例实体:

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

so when I do this: 所以当我这样做时:

someParentTableRepository.softDelete(someParentTableId);

only the someParentTable's deleteflag is marked Y. However, I wud like all the SomeChildTable associated with it to be soft deleted as well. 只有someParentTable的deleteflag标记为Y。但是,我希望将与其关联的所有SomeChildTable也都进行软删除。

Is there a way to achieve this? 有没有办法做到这一点? I m using spring data jpa. 我正在使用spring数据jpa。 Feel free to ask for more details if required. 如果需要,请随时询问更多详细信息。

Soft delete is not propagated because it is not one of the default repository methods. 不传播软删除,因为它不是默认的存储库方法之一。 You can check the interface here: 您可以在此处检查界面:

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

So JPA will not propagate it because it is some strange method which is not part of the interface and Spring doesn't know about it. 所以JPA不会传播它,因为它是一种奇怪的方法,它不是接口的一部分,而Spring对此一无所知。 That's why it won't propagate even with cascade all. 这就是为什么即使全部级联也不会传播的原因。 You should override the delete() method and make it do a soft delete to comply with the interface. 您应该重写delete()方法,并使其进行软删除以符合该接口。

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

Add a hard delete method if you would need that ;) This is the better solution because delete() is the default method that should be called in the code and it should have the default behavior. 如果需要,则添加硬删除方法;)这是更好的解决方案,因为delete()是应在代码中调用的默认方法,并且应具有默认行为。 Otherwise somewhere in the code people will write delete() by habit instead of softDelete() and you will have problems. 否则,人们会在代码中的某些地方按习惯而不是softDelete()编写delete(),这样您就会遇到问题。

Also there is this anotation which works with hibernate on the entity class. 还有一个注释,它在实体类上与休眠一起使用。

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

I am not sure about the exact syntax but it overrides the default delete. 我不确定确切的语法,但它会覆盖默认的删除。 I am not sure it is part of spring jpa though 我不确定这是Spring JPA的一部分

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

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