[스프링 데이터 JPA] 논리 삭제 구현

개발연습생log·2023년 1월 5일
0
post-thumbnail

📎 Soft Delete

hard delete vs soft delete

  • hard delete
    • delete 쿼리를 날려서 데이터베이스에서 실제로 삭제하는 방법
  • soft delete
    • 실제로 데이터베이스에서 데이터를 삭제하는 것이 아닌, 테이블에 deletedAt과 같은 필드를 추가해주고, update 쿼리를 날려 deletedAt 값을 변경해주는 방법

soft delete 구현 방법

  • @SQLDelete
    • 엔티티 삭제가 발생했을 때 delete 쿼리 대신 실행 시켜줄 커스텀 sql 구문을 실행
    • @SQLDelete(sql = "UPDATE table SET deleted = true WHERE id = ?")
  • @Where
    • soft delete 처리를 하는 경우 조회 요청시 삭제처리되지 않은 데이터만 조회해야 한다.
    • 해당 어노테이션은 where 구문을 의미하는 어노테이션
    • 모든 sql 요청에 where 구문이 들어간다.
    • 해당 어노테이션을 사용하여 deletedAt가 null인 데이터만 가져올 수 있다.
  • comment 엔티티
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Getter
@Where(clause = "deleted_at IS NULL")
@SQLDelete(sql = "UPDATE comment SET deleted_at = CURRENT_TIMESTAMP where id = ?")
public class Comment extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String comment;

    @ManyToOne
    @JoinColumn(name = "userId")
    private User user;

    @ManyToOne
    @JoinColumn(name = "postId")
    private Post post;

    public static Comment of(String comment, User user, Post post) {
        return Comment.builder()
                .comment(comment)
                .user(user)
                .post(post)
                .build();
    }

    public void modify(String comment) {
        this.comment = comment;
    }
}

연관관계 삭제

  • CascadeType.REMOVE
    • 부모 엔티티가 삭제되면 자식 엔티티도 삭제된다.
    • 부모 엔티티가 자식 엔티티와의 관계를 제거해도 자식 엔티티는 삭제 되지 않고 그래도 남아있는다.
  • orphanRemoval = true
    • 부모 엔티티가 삭제되면 자식 엔티티도 삭제된다.
    • 부모 엔티티가 자식 엔티티의 관계를 제거하면 자식은 고아로 취급되어 그대로 삭제된다.
  • commentpost 에서 관계를 끊으면 삭제되는 관계이기 때문에 해당 프로젝트에서는 orphanRemoval=true 옵션을 사용했다.
  • Post 엔티티
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Getter
@Where(clause = "deleted_at IS NULL")
@SQLDelete(sql = "UPDATE post SET deleted_at = CURRENT_TIMESTAMP where id = ?")
public class Post extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;
    private String body;

    @ManyToOne
    @JoinColumn(name = "userId")
    private User user;

    @OneToMany(mappedBy = "post", fetch = FetchType.LAZY, orphanRemoval = true)
    private List<Comment> comments;

    public static Post of(String title, String body, User user) {
        return Post.builder()
                .title(title)
                .body(body)
                .user(user)
                .build();
    }

    public void modify(String title, String body) {
        this.title = title;
        this.body = body;
    }
}

📄 참고

profile
주니어 개발자를 향해서..

0개의 댓글