티스토리 뷰
영속성 전이(CASCADE)
- 즉시 로딩, 지연 로딩, 연관관계 매핑과 전혀 관계가 없음.
영속성 전이: 저장
영속성 전이: CASCADE - 주의!
CASCADE의 종류
예제
Parent
@Entity
@NoArgsConstructor
public class Parent {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent") // 양방향 매핑 완료
private List<Child> childList = new ArrayList<>();
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;
}
// 연관관계 편의 메서드 만들기
public void addChild(Child child) {
childList.add(child);
child.setParent(this);
}
}
child
@Entity
@NoArgsConstructor
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
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
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);
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace(); // 하나 찍어봄
} finally {
em.close();
}
emf.close();
}
}
이렇게 하면 persist가 3번이 된다.
확인
13:33:35.237 [main] DEBUG org.hibernate.SQL -
// Parent 1번, Child 2번
Hibernate:
/* insert inflearn.exjpa.jpaExample.Parent
*/ insert
into
Parent
(name, id)
values
(?, ?)
Hibernate:
/* insert inflearn.exjpa.jpaExample.Child
*/ insert
into
Child
(name, parent_id, id)
values
(?, ?, ?)
Hibernate:
/* insert inflearn.exjpa.jpaExample.Child
*/ insert
into
Child
(name, parent_id, id)
values
(?, ?, ?)
그런데 나는 persist() 3번이 아니라, Parent 중심으로 코드를 짜고 있으므로
Parent가 책임지고 관리를 해줬으면 좋겠다.
(parent가 persist() 될 때 child가 자동으로 persist() 되었으면 좋겠다.)
무작정
em.persist(child1);
em.persist(child2);
이거 두 개 지워버리면 에러 나옴.
이 때 쓰는 게 CASCADE !!!
Parent에
@OneToMany(mappedBy = "parent",cascade = CascadeType.ALL) // 양방향 매핑 완료, CASCADE옵션 추가
private List<Child> childList = new ArrayList<>();
추가,
JPAMain은
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);
em.persist(parent);
// CASCADE 옵션 집어넣고 아래 두 개는 지운다.
// em.persist(child1);
// em.persist(child2);
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace(); // 하나 찍어봄
} finally {
em.close();
}
emf.close();
}
}
이렇게 만들고 실행하면
13:39:19.693 [main] DEBUG org.hibernate.SQL -
Hibernate:
/* insert inflearn.exjpa.jpaExample.Parent
*/ insert
into
Parent
(name, id)
values
(?, ?)
13:39:19.696 [main] DEBUG org.hibernate.SQL -
Hibernate:
/* insert inflearn.exjpa.jpaExample.Child
*/ insert
into
Child
(name, parent_id, id)
values
(?, ?, ?)
13:39:19.697 [main] DEBUG org.hibernate.SQL -
Hibernate:
/* insert inflearn.exjpa.jpaExample.Child
*/ insert
into
Child
(name, parent_id, id)
values
(?, ?, ?)
똑같이 세 번이 나온다!
오랜만에 H2 가서 확인해보아도
즉시 로딩, 지연 로딩, 연관관계 매핑 차원이 아니라,
Parent를 persist() 할 때, 얘 밑에 있는 애들도 같이 persist() 를 날려줄거야 하는 게 CASCADE
주의할 게 있다.
CASCADE 사용 조건
(반드시 지켜야 탈이 안 난다)
728x90
반응형
'[개발] - Spring > JPA 공부' 카테고리의 다른 글
실전 예제 - 5. 연관관계 관리 (0) | 2023.08.25 |
---|---|
고아 객체, 그리고 생명 주기 (0) | 2023.08.25 |
지연 로딩 활용 (0) | 2023.08.24 |
즉시 로딩 (0) | 2023.08.24 |
지연 로딩 (0) | 2023.08.24 |
Comments