简体   繁体   中英

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. I am trying achieve this using JPA in a generic way and I would like a JPA solution if possible. deleteFlag is the flag to soft delete which is set to Y or 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:

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

Is there a way to achieve this? I m using spring data 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

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. 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.

@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. Otherwise somewhere in the code people will write delete() by habit instead of softDelete() and you will have problems.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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