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

chiyongs·2022년 6월 30일
4
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개의 댓글

관련 채용 정보