[JPA] 영속성 전이(cascade)

728x90

들어가며


영속성 전이는 엔티티의 영속성 상태 변화를 줄 때 연관된 엔티티에도 함께 적용하는 것이다

예를 들어 엔티티를 저장할 때 연관된 엔티티도 함께 저장하고, 엔티티를 삭제할 때 연관된 엔티티도 함께 삭제하는 것이 영속성 전이 이다

 

영속성 전이를 적용하는 방법은 간단하다

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinColumn(name = "user_id")
private User user;

 

연관관계 설정시 옵션에 cascade 속성값을 지정해주면 된다

cascade = CascadeType.(*)

 

위 설정을 PERSIST 로 하게되면 연관된 엔티티도 함께 저장을 시킨다

 

EntityManger em = EntityManagerFactory.createManger();

em.getTransaction().begin();

User user = new User("1@naver.com","JVM",new Date());
MemberShipCard memberShipCard = new MemberShipCard("1234",user,new Date());
em.persist(memberShipCard); // 연관된 user 도 영속 객체로 추가를 한다.

em.getTransaction().commit();

 

따로 cascade 속성을 설정하지 않으면, 아무런 영속성 전이를 하지 않는다

cascade 속성은 배열을 값으로 가지고 있어 여러개의 속성을 설정할 수 있다

public enum CascadeType {
    ALL,
    PERSIST,
    MERGE,
    REMOVE,
    REFRESH,
    DETACH;

    private CascadeType() {
    }
}

 

enum 으로 구현이 되어 있으며 위 속성을 상황에 맞춰 사용할 수 있다.

 

 

사용방법은 아래와 같다.

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.속성 )

 

영속성 전이는 모든 연관관계에 대해 적용할 수 있다


ex) @OneToOne, @OneToMany, @ManyToOne, @ManyToMany etc

 

 

영속성 전이 주의 사항


영속성 전이가 개발할 때 편하긴 하지만 남용하면 안된다.
특히 CascadeType.REMOVE 는 주의해서 사용해야 한다.

Entity 는 독립적인 라이프사이클을 가지고 있다

그러므로 엔티티를 삭제한다고 해서 연관된 엔티티를 함께 삭제하는 경우는 드물다

보통 엔티티를 삭제하면 연관된 엔티티를 삭제하기 보다는 연관을 Null 로 할당하거나 컬렉션 연관에서 삭제하는 것이 더 일반적인 방법이다

예를 들어 User 가 게시판에 작성한 글을 삭제한다고 해서 User 를 삭제하지는 않을 것이다

그냥 User 엔티티에서 작성한 글을 연관만 제거할 것이다

REMOVE 와 달리 저장하는 것은 연관된 엔티티를 함께 저장해야 정상 동작하므로 CascadeType.PERSIST 는

보통 문제를 일으키지 않는다

 

위 속성은 개발시 편의성을 제공해주는건 분명히 맞다

하지만 자동으로 뭔가 한다는 부분에서 생산성은 증가하지만 잘모르고 사용한다면 나중에 큰 낭패를 볼 수도 있다

명시적인 내용이 사라지는 만큼 나중에 엔티티 간의 관계를 변경할 때 놓치기 쉬운 부분이다

cascadeType.PERSIST 를 유용하게 사용하기 위해서는 제일 먼저 도메인 파악이 제일 중요하다

내 비즈니스랑 도메인을 잘 알지 못하면 설계가 잘못될 것이고 잘못된 설계는 연관 관계에도 분명 영향을 줄 것이다

그 상태로 cascadeType.PERSIST 를 통해 여러 엔티티를 한꺼번에 insert 를 하게 된다면 다시 처음으로 돌아가 에러를 찾고 연관관계를 바꾸는 번거로움이 생길 것 입니다.

 

728x90