ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #JPA-15 속성 전이: CASCADE
    JPA 2021. 2. 19. 17:55

    [출처] 인프런 김영한 강사님 -자바 ORM 표준 JPA 프로그래밍 기본

     

    속성 전이: CASCADE

    (즉시,지연 로딩, 연관관계 설정과 전혀 관계가 없다. )


    • 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 


    • 예: 부모 엔티티를 저장할 때 자식 엔티티도 함께 저장.

     

    속성 전이: 저장

    Parent class

    package hello.jpa;
    
    import javax.persistence.*;
    import java.util.ArrayList;
    import java.util.List;
    
    @Entity
    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);
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<Child> getChildList() {
            return childList;
        }
    
        public void setChildList(List<Child> childList) {
            this.childList = childList;
        }
    }
    

    Child class

    package hello.jpa;
    
    import javax.persistence.*;
    
    @Entity
    public class Child {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String name;
    
        @ManyToOne
        @JoinColumn(name = "parent_id")
        private Parent parent;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Parent getParent() {
            return parent;
        }
    
        public void setParent(Parent parent) {
            this.parent = parent;
        }
    }
    

    JpaMain Class

    Parent parent  = new Parent();
    
    Child child1 = new Child();
    Child child2 = new Child();
    parent.addChild(child1);
    parent.addChild(child2);
    
    em.persist(parent);
    // em.persist(child1);
    // em.persist(child2);
    //이건 귀찮다 parent 중심으로 개발을 하고 싶은데 parent를 persit할때 child를 자동으로 persit하고 싶어
    //이때 쓰는 것이 casecade
    tx.commit();

    casecade를 하지 않으면 em.persist를 주석 한부분처럼 두번 더써야하는데 casecade 함으로서 1번이면 해결된다.

    simple하게 parent를 persist할때 연관된 애들까지 persist를 할꺼야!!

     

     

    @OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST)

    속성 전이: CASCADE - 주의!


    • 속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없음

     

    • 엔티티를 속화할 때 연관된 엔티티도 함께 속화하는 편리함 을 제공할 뿐 그 이상 그 이하도 아니다.

     

     

    CASCADE의 종류 

    • ALL: 모두 적용  (life cycle을 다 맞춰야해 하면 ALL)

    • PERSIST: 영속 (저장할때만 life cycle맞추고 나머지는 따로 돌꺼야 하면 PERSIST)

    • REMOVE: 삭제 

    • MERGE: 병합 

    • REFRESH: REFRESH 

    • DETACH: DETACH

     

    CASCADE를 언제쓸거야?

    • 일대다에는 다 casecade를 하느냐?? ->아니다

    하나의 부모가 자식들을 관리할때는 의미가 있다. (소유자가 하나일 때), 단일 entity에 완전히 종속적일때

      parent와 child의 life cycle이 완전히 똑같을때(등록하거나 삭제할때 가 유사할때)

      (EX O) 게시판 첨부파일 , 첨부파일 데이터나 경로 첨부파일 경로는 한 게시판에서만 관리하기 때문이다.)

      (EX X)  파일을 여러군데서 다른 ENTITY에서 관리할 경우에는 쓰면안됨

                 ex) Parent말고 Member가 child를 알고있다? 이경우에 사용 x)

      

    고아 객체

    • 고아 객체 제거: 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제

    orphanRemoval = true

    • Parent parent1 =  em.find(Parent.class, id); //찾음

       parent1.getChildren().remove(0);

       //자식 엔티티를 컬렉션에서 제거(연관관계 제거)

    • DELETE FROM CHILD WHERE ID = ? //delete 쿼리가 나간다.

                Parent parent  = new Parent();
    
                Child child1 = new Child();
                Child child2 = new Child();
                parent.addChild(child1);
                parent.addChild(child2);
    
                em.persist(parent);
    
                em.flush();
                em.clear();
    
                Parent findParent = em.find(Parent.class, parent.getId());
                findParent.getChildList().remove(0);
    
                tx.commit();

     

    고아 객체 - 주의

    • 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능

     

    참조하는 곳이 하나일 때 사용해야함!

     

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

     

    • @OneToOne, @OneToMany만 가능

     

    • 참고: 개념적으로 부모를 제거하면 자식은 고아가 된다. 따라서 고아 객체 제거 기능을 활성화 하면,

             부모를 제거할 때 자식도 함께 제거된다.

             이것은 CascadeType.REMOVE처럼 동작한다.

    casecade를 지운 상태

    JpaMain class

               Parent parent  = new Parent();
    
                Child child1 = new Child();
                Child child2 = new Child();
                parent.addChild(child1);
                parent.addChild(child2);
    
                em.persist(parent);
                em.persist(child1);
                em.persist(child2);
    
                em.flush();
                em.clear();
    
                Parent findParent = em.find(Parent.class, parent.getId());
                em.remove(findParent); //parent를 지우면?
    
                tx.commit();

    em.remove로 parent를 지우게 되면 parent가 지워진다.  그러면 orphanRemoval 입장에서는 childList까지 다 지우게됨.

     ALL

    애를지우면 당연히 delete가 전파되기 때문에 child 및 parent를 다 지운다.

     

    속성 전이 + 고아 객체, 생명주기

    CascadeType.ALL + orphanRemovel=true

     

    • 스스로 생명주기를 관리하는 엔티티는 em.persist()로 영속화, em.remove()로 제거

    • 두 옵션을 모두 활성화 하면 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있음

    (자식을 remove하지 않아도 자식이 지워진다. )

     -> 생명주기를 parent는 jpa를 통해서 관리되지만 child의 생명주기는 parent가 관리한다.

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

    (repository는 Aggregate Root만 contact하고 나머지는 repository를 만들지 않는 것 이 더낫다. Aggregate Root 관리하는 밑에 애들은 repository를 따로 만들지않고 Aggregate Root 통해서 생명주기를 관리한다.)

     

     

     

    실전 예제 - 5.연관관계 관리


    글로벌 페치 전략 설정


      • 모든 연관관계를 지연 로딩으로 

      • @ManyToOne, @OneToOne은 기본이 즉시 로딩이므로 지연 로딩으로 변경


    속성 전이 설정

     

     • Order -> Delivery를 속성 전이 ALL 설정  

     • Order -> OrderItem을 속성 전이 ALL 설정

    'JPA' 카테고리의 다른 글

    #JPA-17 JPA가 지원하는 다양한 쿼리 방법  (0) 2021.02.23
    #JPA-16 값 타입  (0) 2021.02.22
    #JPA-14 즉시 로딩과 지연 로딩  (0) 2021.02.19
    #JPA-13 프록시  (0) 2021.02.19
    #JPA-12 상속관계 매핑  (0) 2021.02.19

    댓글

Designed by Tistory.