생성시간과, 삭제시간은 jpaAuditing으로 기록이 가능했는데, 삭제시점을 자동을 체크해주고 싶어서 찾아보니 jpaAuditing에는 없었다 흨,,ㅠ
그러다
하이버네이트에서, delete 시점을 체크할 수 있는 @SqlDelete 와 default 조건절을 붙히는 @where 를 발견했다..!
Soft Delete
ex) `UPDATE table SET delete = 1 WHERE id = 2` 형태로 ROW가 삭제 되지 않고 flag를 통한 제어 하는 방식
delete가 되더라도, 데이터를 지우는게 아닌, column 값을 변경하여, 데이터를 제어하는 방법이다,
@SQLDelete Annotation
@SQLDelete 어노테이션을 통해, 실제 삭제가 이루어질때 수행 할 쿼리를 적으면 된다.
- ex) @SQLDelete("UPDATE product SET del=1 WHERE id = ?")
- 그럼 productRepository.deleteById(1L) 형태로 진행이 되면 'DELETE FROM product WHERE id = 1' 형태로 쿼리가 동작 하는 것이 아닌
- 'Update product SET del 1 WHERE id = 1' 형태로 쿼리가 발생되어 동작하게 된다.
@Where Annotation
- @Where 어노테이션은 Entity의 Default 조건을 지정 할 수 있는 어노테이션 이다.
- 장점은 'Soft Delete'로 인하여, 객체 그래프에서 발생 할 수 있는 문제를 신경쓰지 않아도 된다.
- 또한,@OneToMany, @ManyToOne 등의 조인이 걸린 경우에도 따로 쿼리 조건을 지정 할 수 있기 때문에 편해진다.
단점은, 무조건 조건이 적용 되기 때문에, 삭제된 걸 가져와야 하는 상황에는 또 애매해진다.
(이 경우는 @FilterDef을 활용하면 된다고 한다는데,, 음)
soft delete 적용해보기
@MappedSuperclass // 맴버변수가 컬럼이 되도록
@EntityListeners(AuditingEntityListener.class) // 변경되었을 때 자동으로 기록합니다.
public class Timestamped {
@CreatedDate // 최초 생성 시점
private LocalDateTime createdAt;
@LastModifiedDate // 마지막 변경 시점
private LocalDateTime modifiedAt;
//삭제 시점
private LocalDateTime deletedAt;
}
@Getter
@Entity
@ToString
@NoArgsConstructor
@Where(clause = "deleted_at IS NULL")
@SQLDelete(sql = "UPDATE post SET deleted_at = CURRENT_TIMESTAMP where id = ?")
public class Post extends Timestamped {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
@Column
private Long id;
//제목
@Column
String title;
//내용
@Column
String contents;
@Builder
public Post(String title, String contents) {
this.title = title;
this.contents = contents;
}
}
참고
'Spring > Spring Boot' 카테고리의 다른 글
[Spring] 무한스크롤 구현 및 성능 개선 하기 - No Offset 페이지네이션 (6) | 2022.08.12 |
---|---|
[Spring] 스프링 순환 참조, 무한 재귀 해결하기 (DTO, JsonIgnore) (0) | 2022.04.20 |
[JPA] Fetch join 과 Join 차이점 (0) | 2022.04.20 |
[Spring] 스프링 부트 JPA 페이징 성능 개선 - querydsl 페이지네이션(오프셋 페이징, 커서 페이징, querydsl 정렬) (0) | 2022.04.10 |
[Spring/스프링] springboot gradle - XSS 스크립트 오류 해결하기 (with @RequestBody) (4) | 2022.04.05 |