[JPA] 영속성 전이 & CASCADE?? 그게 뭔데?

chiyongs·2022년 6월 30일
3
post-thumbnail

영속성 전이란? 👨‍👧

영속성 전이는 JPA에서 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용합니다.

예를 들어, Parent-Child 관계에서 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장되게 하거나, 부모 엔티티를 삭제할 때 자식 엔티티도 함께 삭제하고 싶을 때 사용합니다.

cascade 옵션은 JPA에서 @ManyToOne@OneToMany관계에서 사용할 수 있습니다.
양방향 일대다 관계인 게시글과 댓글로 예시를 보여드리겠습니다.

예시

@Entity
public class Article { // 게시글 엔티티

    @Id @GeneratedValue
    @Column(name = "article_id")
    private Long id;

    private String title;
    private String content;

    @OneToMany(mappedBy = "article")
    private List<Comment> comments = new ArrayList<>();
    
    //== 연관관계 메서드 ==//
    public void addComment(Comment comment) {
        comments.add(comment);
        comment.belongToArticle(this);
    }
    
}
@Entity
public class Comment { // 댓글 엔티티

    @Id @GeneratedValue
    @Column(name = "comment_id")
    private Long id;
    
    private String content;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "article_id")
    private Article article;

    //== 연관관계 메서드 ==//
    public void belongToArticle(Article article) {
        this.article = article;
    }

}
@Transactional
@Service @RequiredArgsConstructor
public class ArticleRegisterService {

    private final ArticleRepository articleRepository;

	//** 예시입니다 **//
    public Long addArticle() {
		Article article = new Article();
        article.setTitle("예시 제목입니다.");
        article.setContent("예시 내용입니다~~");
        
        Comment comment1 = new Comment();
        comment1.setContent("첫 댓글입니다");
        article.addComment(comment1);
        
        Comment comment2 = new Comment();
        comment2.setContent("두 번째 댓글입니다");
        article.addComment(comment2);
       
        return articleRepository.save(article).getId();
    }
}

위와 같은 상태에서 addArticle() 메서드가 실행된다면 엔티티들의 테이블은 다음과 같습니다.

  • Article Table
article_idtitlecontent
1예시 제목입니다.예시 내용입니다~~
  • Comment Table
comment_idcontentarticle_id

보이시는 것과 같이 Comment에 대한 데이터는 테이블에 저장되지 않았습니다.
하지만, cascade 옵션을 사용한다면!!

@OneToMany(mappedBy = "article", cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();

다음과 같이 테이블에 변화가 생깁니다.

  • Article Table
article_idtitlecontent
1예시 제목입니다.예시 내용입니다~~
  • Comment Table
comment_idcontentarticle_id
2첫 댓글입니다1
3두 번째 댓글입니다1

어떻게 이런 일이 가능할까요??
👉 그것은 바로 cascade를 통해 Article 엔티티를 영속 상태로 만들 때 연관된 Comment 엔티티도 함께 영속 상태로 만들고 데이터를 저장하기 때문입니다.

Cascade 종류

그렇다면, cascade 옵션의 종류를 무엇이 있을까요??

  • CascadeType.ALL : 모든 Cascade 옵션을 적용합니다.
  • CascadeType.PERSIST : 엔티티를 영속화할 때, 연관된 엔티티도 함께 영속화합니다.
  • CascadeType.REMOVE : 엔티티를 제거할 때, 연관된 엔티티도 함께 제거합니다.
  • CascadeType.MERGE : 엔티티 상태를 병합할 때, 연관된 엔티티도 함께 병합합니다.
  • CascadeType.REFRESH : 부모 엔티티를 Refresh하면, 연관된 엔티티도 함께 Refresh됩니다.
  • CascadeType.DETACH : 부모 엔티티를 Detach하면, 연관된 엔티티도 함께 Detach됩니다.

대부분의 경우, CascadeType.ALL을 사용하지만, 상황과 목적에 맞게 사용하시면 될 것 같습니다.

참고

영속성 전이는 연관관계를 매핑하는 것과는 아무 관련이 없습니다.
그저 엔티티를 영속화할 때 연관된 엔티티도 함께 영속화하는 등의 편리함을 제공할 뿐입니다.
또한, 연관관계에서 단 하나의 부모에 종속하는 경우에만 사용하는 것이 좋습니다.


김영한님의 자바 ORM 표준 JPA 프로그래밍 강의와 스스로 공부한 내용을 토대로 제작한 글입니다.
잘못된 내용이나 오타가 있다면 댓글로 알려주시면 감사하겠습니다!

0개의 댓글