자바 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;
}
}
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
속성을 제공한다.
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 | DESCRIPTION |
---|---|
PERSIST | 객체 영속화 시 연관된 Entity 객체도 함께 영속화 진행 Parent 를 영속화 했을 때 Children 의 Child 도 함께 영속화 |
REMOVE | 영속화 된 객체 삭제 시 연관관계 Entity도 함께 삭제 Parent 를 삭제 시 Children 의 Child 자동 삭제 |
ALL | PERSIST + REMOVE |
MERGE | 객체 병합 시 연관된 객체도 모두 병합 Parent 를 병합 했을 때 Children 의 Child 도 함께 병합 |
DETACH | 객체를 준영속상태로 변환하면 연관된 객체도 준영속 상태로 변환 |
REFRESH | 객체를 새로 고침하면 연관된 객체도 새로 고침 |
연관된 엔티티의 생명주기를 관리할 수 있다.
객체 주제에 꽤나 슬픈 이름을 가지고 있다.
부모 엔티티와 연관관계가 끊어진 자식 엔티티를 말한다.
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.Remove
와orphanRemoval = true
의 차이는
CascadeType.Remove
:Parent
엔티티가 삭제되면 연관된Child
엔티티 삭제
orphanRemoval = true
:Parent
엔티티와 연관관계가 끊긴Child
엔티티만 삭제
연관관계가 @OneToMany
, OneToOne
일 때 사용하는 것이 좋다.