1. 개요
김영한 님의 '자바 ORM 표준 JPA 프로그래밍 - 기본편' 을 들으면서 정리하는 포스팅입니다.
https://www.inflearn.com/course/ORM-JPA-Basic
자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 | 김영한 - 인프런
김영한 | JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 실무에서도
www.inflearn.com
2. 영속성 전이란?
영속성 전이는 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태를 만드는 것이다.
부모 엔티티를 저장할 때 자식 엔티티도 함께 저장하는 경우, 부모 엔티티를 삭제할 때 자식 엔티티도 함께 삭제해야 하는 경우에 유용하게 사용된다.
아래 예시를 보자.
3. CASECADE 사용 예시
casecade 옵션은 @ManyToOne, @OneToMany, @OneToOne 관계에서 사용할 수 있다.
CASECADE 예제 코드
- Parent(부모) - Child(자식) 관계에서, 부모는 다수의 자식을 가진다.
- 이 때 CasecadeType.ALL을 사용하여 부모 엔티티와 자식 엔티티의 영속성을 함께 관리하도록 설정할 수 있다.
@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 void removeChild(Child child) {
childList.remove(child);
child.setParent(null);
}
// getter, setter
}
@Entity
public class Child {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
// getter, setter
}
영속화 예제
Child child1 = new Child();
child1.setName("child1");
Child child2 = new Child();
child2.setName("child2");
Parent parent = new Parent();
parent.setName("parent1");
parent.addChild(child1); // child1 추가
parent.addChild(child2); // child2 추가
em.persist(parent); // parent 영속화
영속화 실행 결과
- parent를 영속화 할 때 연관된 자식 Child 엔티티들이 자동으로 영속상태가 된다.
삭제 예제
Parent findParent = em.find(Parent.class, parent.getId());
em.remove(findParent); // 삭제
삭제 실행 결과
- 쿼리 결과를 보면 연관된 자식 엔티티를 모두 삭제하는 것을 볼 수 있다.
4. CASECADE의 종류
JPA에서 여러 종류의 Casecade 옵션을 제공한다.
- CasecadeType.ALL: 모든 전이 작업(영속, 병합, 삭제, 고아 객체 제거 등) 을 수행
- CasecadeType.PERSIST: 부모 엔티티가 영속화 할 때, 연관된 자식 엔티티도 함께 영속화
- CasecadeType.MERGE: 부모 엔티티가 병합될 때, 연관된 자식 엔티티도 함께 병합
- CasecadeType.REMOVE: 부모 엔티티가 삭제될 때, 연관된 자식 엔티티도 함께 삭제
- CasecadeType.REFRESH: 부모 엔티티가 새로고침 될 때, 연관된 자식 엔티티도 함께 새로 고침
- CasecadeType.DETACH: 부모 엔티티가 준영속 상태가 될 때, 연관된 자식 엔티티도 함께 준영속 상태
대부분 ALL을 사용하지만, 상황과 목적에 따라 적절하게 설정하면 된다.
5. 고아객체와 orphanRemoval 옵션
orphanRemoval 옵션은 JPA에서 고아 객체를 자동으로 삭제하도록 도와주는 옵션으로, 부모-자식 관계에서 자식 엔티티가 부모와의 관계에서 제거되었을 때 해당 자식 엔티티를 데이터베이스에서도 삭제하는 역할을 한다.
여기서 고아 객체란 자식 엔티티가 부모와의 연관관계가 끊어져 더 이상 관리되지 않는 객체를 말한다.
CasecadeType.REMOVE, orphanRemoval 옵션은 비슷한 역할은 하지만 동작 방식에 차이가 있다.
orphanRemoval VS. CasecadeType.REMOVE
기능 | orphanRemoval = true | CasecadeType.REMOVE |
목적 | 고아 객체를 삭제 | 부모 엔티티 삭제 시 연관된 자식 엔티티도 삭제 |
적용 범위 | 자식 엔티티와 부모와의 관계가 제거될 때 | 부모 엔티티 삭제 작업에만 적용 |
작동 방식 | 부모 컬렉션에서 자식을 제거하면 자식 엔티티 삭제 | 부모 엔티티 삭제 시 자식 엔티티도 함께 삭제 |
연관성 | 부모-자식 관계에 중점 | 엔티티의 생명주기에 중점 |
orphanRemoval 사용 예시
@Entity
public class Parent {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) // orphanRemoval 옵션 설정
private List<Child> childList = new ArrayList<>();
public void addChild(Child child) {
childList.add(child);
child.setParent(this);
}
public void removeChild(Child child) {
childList.remove(child);
child.setParent(null);
}
// getter, setter
}
Parent findParent = em.find(Parent.class, parent.getId());
Child targetChild = findParent.getChildList().get(0);
findParent.removeChild(targetChild); // 부모 컬렉션에서 자식 제거
실행결과
5. CASECADE 사용 시 고려할 점
casecade는 연관관계 매핑과는 직접적인 관련은 없고, 영속성 전이를 통해 연관된 엔티티도 함께 영속화(또는 삭제)할 수 있어 관리 측면에서 편리함을 제공할 뿐이다.
연관관계에서 무조건 적으로 사용하는 것은 옳지 않다.
casecade 옵션은 DB에 직접적인 영향을 끼치므로, 자식 엔티티가 부모 엔티티에 종속적인 경우에 사용을 고려하도록 하자.
'Programming > Java' 카테고리의 다른 글
[JPA] JPQL 기본 문법 정리 (0) | 2025.01.08 |
---|---|
[JPA] 값 타입 정리(기본값, 임베디드, 컬렉션) (0) | 2025.01.02 |
[JPA] Entity 로딩 전략과 프록시(Proxy) (0) | 2024.12.23 |
[JPA] JPA에서 DB 슈퍼-서브 타입 구현하는 방법 (0) | 2024.12.20 |
[JPA] Entity 연관 관계 매핑(단방향/양방향, 연관관계주인, 다중성) (0) | 2024.12.13 |