본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


JPA

JPA 공부 10 - 영속성 전이 (cascade)

반응형

cascade

 

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

 

예 : 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장하게 한다.

 

 

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Parent {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "parent",cascade = CascadeType.ALL)
    private List<Child> childList = new ArrayList<>();

    public void addChild(Child child){
        childList.add(child);
        child.setParent(this);
    }

}

 

 

parent 와 child   @ManyToOne 으로 연결되어 있다 .   이때 cascade 가 지정 안되어 있다면 persist 하는 것은 아래코드와 같을 것이다.

 

 Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);

em.persist(parent);
em.persist(child1);
em.persist(child2);

 

지금은 몇개 안되지만 여러개라면 분명 귀찮은 일이 될 것이다 .  

 

 

cascade를  @OneToMany(mappedBy = "parent",cascade = CascadeType.ALL) 와 같이 설정한다면 ?

 

 Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);
em.persist(parent);

 

 

부모 엔티티만 저장했는데 자식들도 알아서 저장됬다 

 

 

영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없다 .

 

영속화할 때 연관된 엔티티도 함꼐 영속화하는 편리함을 위해서 사용한다. 그 뿐이다. 

 

 

언제 쓰는 것이 좋은까 ? 

 

하나의 부모만 자식클래스를 관리할 때.

부모와 자식 엔티티 라이프 사이클이 같을때 

 

 

언제 쓰지 말아야하나 

 

자식엔티티가 부모하나 뿐만아니라 다른데서도 같이 사용할 때 

 

 

 

고아 객체

 

 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 말한다.  

 

 고아 객체 제거

 

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Parent {

    @Id
    @GeneratedValue
    private Long id;

    private String name;


    @OneToMany(mappedBy = "parent",cascade = CascadeType.ALL,orphanRemoval = true)
    private List<Child> childList = new ArrayList<>();

    public void addChild(Child child){
        childList.add(child);
        child.setParent(this);
    }

}

 

 

orphanRemoval = true 옵션을 주면된다  이 경우에 연관관계가 맺어진 자식객체가 컬랙션에서 빠지면 해당 고아객체에 대해 자동으로 delete쿼리가 나간다

 

Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);
em.persist(parent);

em.flush();
em.clear();

Parent searchedParent = em.find(Parent.class, parent.getId());
//부모객체의 컬랙션에서 자식 객체 삭제 
searchedParent.getChildList().remove(0);

 

delete  쿼리가 잘 나갔다 .

 

언제 사용하나?

 

참조하는 곳이 하나일 때 사용해야한다. 

 

특정 엔티티가 개인 소유할 때 사용

 

@OneToOne 혹은 @OneToMany 에서만 사용하는 것이 좋다 . 

 

 

부모를 제거하면 자식은 고아가 된다 . 따라서 고아 객체 제거 기능을 활성화 하면 ,부모를 제거할 때 자식도 함께 제거된다. 

 

cascade 와 orphanRemoval을 함께 사용하면 부모 객체에서 자식엔티티의 라이프 사이클을 관리할 수 있다. 

 

cascade 는 생성을 해주고 , orphanRemoval은 삭제를 해준다 .

 

도메인 주도 설계 (DDD ) 의 Aggregate Root 개념을 구현할 때 유용하다 . 

 

Aggregate Root 는 리파지토리는 Aggregate Root만 컨텍하고 나머지 자식객체에 대해서는 Aggregate Root를 따로 만들지 않는

것을 지향 하는 방식이다. 나머지 객체들은 Aggregate Root 를 통해서 생명주기를 관리한다 .  

 

 

 

 

 

 

반응형