들어가며
영속성 전이는 엔티티의 영속성 상태 변화를 줄 때 연관된 엔티티에도 함께 적용하는 것이다
예를 들어 엔티티를 저장할 때 연관된 엔티티도 함께 저장하고, 엔티티를 삭제할 때 연관된 엔티티도 함께 삭제하는 것이 영속성 전이 이다
영속성 전이를 적용하는 방법은 간단하다
@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 를 하게 된다면 다시 처음으로 돌아가 에러를 찾고 연관관계를 바꾸는 번거로움이 생길 것 입니다.