Spring Boot - JPA 영속성 전이

진경천·2024년 11월 19일

영속성 전이

특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들 때 사용 한다.

예를 들어 서로 양방향으로 연관 관계를 갖는 Post 엔티티와 Comment 엔티티를 영속화한다고 가정해보자

@Entity
@Getter
@Setter
public class Comment {
	@Id
	private Long id;
    
    @ManyToOne
    @JoinColumn(name = "post_id")
    private Post post;   
}

@Entity
@Getter
@Setter
public class Post {
	@Id
    private Long id;
    
    @OneToMany(mappedBy = "post")
    private List<Comment> comments;
}
Post post = new Post();

Comment comment1 = new Comment();
Comment comment2 = new Comment();

comment1.setPost(post);
comment2.setPost(post);

post.getComments().add(comment1);
post.getComments().add(comment2);

em.persist(post);
em.persist(comment1);
em.persist(comment2);

위 같이 Post 엔티티와 Comment 엔티티가 연관관계로 매핑되어 있을 때 Post와 Comment를 각각 영속화 시키는 작업을 진행 한다.

이러한 번거로운 작업을 생략해주는 것이 영속성 전이이다.
Post가 영속 상태가 되면 연관된 Comment도 영속 상태로 전이시키는 것이다.

@Entity
@Getter
@Setter
public class Post {
	@Id
    private Long id;
    
    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
    private List<Comment> comments;
}
em.persist(post)

위와 같이 cascade를 설정해주면 부모 엔티티인 post를 영속화 시킬 때 Post의 필드인 comments도 영속화 시키겠다는 것을 의미한다.

CASCADE의 종류

종류 설명
ALL 모든 작업(상태)에 대해 영속성 전이 (사이클을 전부 맞춰야할 때 사용)
PERSIST Persist 할 때 연관된 엔티티도 Persist
MERGE 엔티티를 영속성 컨텍스트에 Merge 할 때 연관 엔티티도 Merge
REMOVE DB와 영속성 컨텍스트에서 연관 엔티티도 제거
REFRESH 엔티티 새로고침 시 연관 엔티티도 새로고침
DETACH 엔티티를 영속성 컨텍스트에서 Detach 하면 같이 Detach

CASCADE를 사용할 수 있는 조건

  • parent와 child의 라이프 사이클이 동일하거나 유사할 때
  • 단일 소유자일 경우
    (오직 parent만이 child를 소유할 때, 다른 Entity가 child를 소유해서는 안됨)

    📌
    cascade는 주인이 아닌쪽에 걸어주면 된다.
    일반적으로 @OneToMany or OneToOne

고아 객체

부모 엔티티와 연관 관계가 끊어진 자식 엔티티를 고아 객체라고 한다.

Post와 Comment가 양방향 연관관계로 맺어진 경우
게시글에 달린 댓글들은 독립적으로 존재할 수 없기 때문에 게시글이 삭제되는 경우 같이 삭제되어야 한다.

이를 가능하게 해주는 것이 orphanRemoval 옵션이다.

@Entity
@Getter
@Setter
public class Post {
	@Id
    private Long id;
    
    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Comment> comments;
}

orphanRemoval=true VS Cascade.REMOVE

Cascade.REMOVE : 엔티티를 em.remove를 통해 EntityManager가 직접 삭제할 때 자식 엔티티를 삭제
orphanRemoval=true : Cascade.REMOVE 의 기능도 수행하며 엔티티의 리스트에서 요소를 삭제하기만 해도 해당 엔티티가 삭제되는 기능까지 포함

Ref: 브리도의 개발일지

profile
어중이떠중이

0개의 댓글