CasCade

XingXi·2024년 1월 4일
0

JPA

목록 보기
16/23
post-thumbnail

🍕 Reference

자바 ORM 표준 JPA 프로그래밍 : 교보문고
자바 ORM 표준 JPA 프로그래밍 - 기본편 : 인프런

중요하게 생각하는 건

CASCADE 는 연관관계 Mapping 과 연관있는 것이 아니라 연관된 Entity 를 함께 영속화 하는 것이다.

어느 한 객체를 영속화 하면 지정된 객체도 영속화 되는 것을 말한다.

🍇 예시

Parent

@Entity
public class Parent extends BaseEntity
{
    @OneToMany(mappedBy = "parent")
    private List<Child> children = new ArrayList<>();

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

Child

@Entity
public class Child extends  BaseEntity
{
    public Child(String name)
    { this.setName(name); }

    public Child(){}

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent")
    private Parent parent;

    public Parent getParent() {
        return parent;
    }
    public void setParent(Parent parent) {
        this.parent = parent;
    }
}

Parent 와 Child 객체를 영속화 하려면 ..

try
        {
            Child child1 = new Child("one");
            Child child2 = new Child("two");

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

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

            et.commit();

다음과 같이 영속화 하려는 객체의 수만큼 persist를 호출한다.
이런 작업을 줄이기 위해 CASCADE 속성을 제공한다.

CASCADE

🍇 CASCADE 예시

Parent

public class Parent extends BaseEntity
{
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    private List<Child> children = new ArrayList<>();

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

Child

@Entity
public class Child extends  BaseEntity
{
    public Child(String name)
    { this.setName(name); }

    public Child(){}

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent")
    private Parent parent;

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }
}

CASCADE를 이용하여 Parent 와 Child 객체를 영속화

try
        {
            Child child1 = new Child("one");
            Child child2 = new Child("two");

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

            em.persist(parent);
            et.commit();

결과

---
Hibernate: 
    /* insert org.example.entity.Parent
        */ insert 
        into
            Parent
            (createDate, createUser, modifyDate, modifyUser, name, id) 
        values
            (?, ?, ?, ?, ?, ?)
Hibernate: 
    /* insert org.example.entity.Child
        */ insert 
        into
            Child
            (createDate, createUser, modifyDate, modifyUser, name, parent, id) 
        values
            (?, ?, ?, ?, ?, ?, ?)
Hibernate: 
    /* insert org.example.entity.Child
        */ insert 
        into
            Child
            (createDate, createUser, modifyDate, modifyUser, name, parent, id) 
        values
            (?, ?, ?, ?, ?, ?, ?)

Parent 객체만 persist를 호출하여 영속화 했음에도 child 객체들 까지 모두
영속화 되는 것을 볼 수 있다.

CASCADE 는 연관관계 엔티티의 영속성을 정의하는 기능이다

CASCADE 종류

CASCADEDESCRIPTION
PERSIST객체 영속화 시 연관된 Entity 객체도 함께 영속화 진행
Parent를 영속화 했을 때 ChildrenChild 도 함께 영속화
REMOVE영속화 된 객체 삭제 시 연관관계 Entity도 함께 삭제
Parent를 삭제 시 ChildrenChild 자동 삭제
ALLPERSIST + REMOVE
MERGE객체 병합 시 연관된 객체도 모두 병합
Parent를 병합 했을 때 ChildrenChild 도 함께 병합
DETACH객체를 준영속상태로 변환하면 연관된 객체도 준영속 상태로 변환
REFRESH객체를 새로 고침하면 연관된 객체도 새로 고침

연관된 엔티티의 생명주기를 관리할 수 있다.

orphan 객체

객체 주제에 꽤나 슬픈 이름을 가지고 있다.
부모 엔티티와 연관관계가 끊어진 자식 엔티티를 말한다.
orphanRemoval = true 를 통해 부모 엔티티와 연관관계가 끊어지면 자동으로 삭제 된다.

🍇 예시

@Entity
public class Parent extends BaseEntity
{
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Child> children = new ArrayList<>();

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

    public List<Child> getChildren() {
        return children;
    }
}

상위 객체에서 연관관계 제거

            Child child1 = new Child("one");
            Child child2 = new Child("two");

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

            em.persist(parent);

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

            Parent findParent = em.find(Parent.class, parent.getId());
            findParent.getChildren().remove(0);

결과

Hibernate: 
    /* delete org.example.entity.Child */ delete 
        from
            Child 
        where
            id=?

Parent 엔티티에서 child collection 에서 지워진 Child 엔티티가 실제로 지워졌다.

CascadeType.RemoveorphanRemoval = true의 차이는
CascadeType.Remove : Parent 엔티티가 삭제되면 연관된 Child 엔티티 삭제
orphanRemoval = true : Parent 엔티티와 연관관계가 끊긴 Child엔티티만 삭제

추가적으로

연관관계가 @OneToMany, OneToOne일 때 사용하는 것이 좋다.

0개의 댓글