이전 글 : 2023.05.09 - [SQL] - Soft Delete, Hard Delete (논리삭제와 물리삭제)
수정 전 코드
현재 멤버 클래스는 다음과 같이 구성되어 있다.
이 중 activated는 현재 해당 멤버가 삭제되었는지를 나타낸다.
activated가 false 이면 삭제된 객체이다 (soft delete )
JPA에서 soft delete를 도와주는 기능을 모를때는 직접 query문을 조작하여 논리 삭제를 진행하였다.
해당 과정에서 논리 삭제를 적용하기 위해서 직접 쿼리문을 이용하여 수정하였다.(수동 soft delete)
하지만 해당 부분을 jpa 어노테이션을 활용하면 자동으로 해결할 수 있다 하여 수정해 보았다
삭제 쿼리 수정
Member Entity클래스에서 delete() 메서드를 삭제하고 아래와 같이 Entity 클래스에 SQLDelete가 수행될 경우에 실행될 sql문을 작성하였다.
후에 service클래스에서 아래와 같이 리파짓 토리에서 삭제할 수 있도록 수정하였다.
@SQLDelete(sql = "UPDATE member SET activated = false WHERE member_id = ?")
테스트 코드를 확인해보면 삭제시에 activated필드만 false로 변경 되는것을 확인할 수 있다.
~~ 참고로 나는 해당 부분에서 데이터베이스 대소문자 구분으로 인해서 오류가 있었다~~
2023.05.12 - [JPA/ORM JPA] - JPA, H2 데이터 베이스 대소문자 구분에러
하지만 soft delete를 제공하게 된다면 조회시마다 해당 조건을 쿼리문에 넣어야 한다. 실제 현업에서는 직접 적으로 쿼리를 작성하는 일이 많다고 하지만 이번에는 JPA 에서 제공해주는 기능을 사용해보았다.
조회 쿼리 수정
아래의 쿼리문을 작성하면 모든 쿼리 실행시에 아래의 쿼리를 추가로 넣어 실행해준다.
@Where(clause = "activated = true")
위의 테스트 코드를 실행하면 activat 가 true인 경우만 조회가 되고, false인 객체는 조회하지 않는것을 확인할 수 있다.
이렇게 코드를 구성하면 SOFT DELETE를 자동으로 구성할 수 있다는 장점이 있다.
하지만 문제는 이렇게 되면 일괄적으로 필터링하기 때문에 만약 탈퇴한 회원들을 보고자 한다면 직접 nativeQuery 옵션을 활용하여 쿼리를 작성해야 한다. 이런 부분을 생각한다면 직접 쿼리에서 확인하는 방법이 나을 수도 있겠다는 생각이 들었다
(참고로 위에 조회 부분을 수정하면 삭제 시에 진행했던 테스트 케이스는 제대로 동작하지 않는다. 조회가 안되기 때문이다)
Where 조건절을 무시하는 쿼리 작성하는 방법
위에서 조회 부분을 수정하면서 삭제시에 진행했던 테스트 케이스가 동작하지 않는다
해당 부분 수정을 위해 where 이 무시되는 경우를 찾아보았다.
JPA의 where조건절을 무시하는 방법은 Native Query를 사용하는 것이다.
상속관계인 경우
soft delete를 처리하는 경우 상속관계인 경우 delete를 하는경우 모든 자식 클래스들은 실제로 삭제가 된다.
그런 경우 아래코드를 자식 엔티티에 작성해주면 된다.
@OnDelete(action = OnDeleteAction.CASCADE)
USER를 FK로 가지고 있는 경우
만약 User가 OneToMany와 같은 관계매핑에서함께 삭제하도록 " cascade = CascadeType.ALL"과 같이 설정 되어있다면 관련 테이블의 값들은 실제로 삭제가 된다. 따라서 이경우에는 종속되지 않도록 하거나 연관된 테이블의 user_id값은 null로 바꿔주는 등의 방법이 있다.
[참고]
https://hello-backend.tistory.com/m/151
https://velog.io/@max9106/JPA-soft-delete
https://jaime-note.tistory.com/450
https://astrid-dm.tistory.com/496
'JPA' 카테고리의 다른 글
JpaAuditing을 이용해서 base entity 생성하기 (1) | 2023.06.24 |
---|---|
JDBC, JPA, ORM (0) | 2023.04.12 |
spring boot 3 Query Dsl적용 (네이티브 쿼리 작성으로 N+1문제 해결) (0) | 2023.03.31 |
@CreationTimestamp, @PrePersist(JPA라이프 사이클 어노테이션) (0) | 2023.03.28 |
엔터티 설계 주의사항 (0) | 2023.02.27 |
댓글