728x90
1. 영속성 전이(CASCADE)
특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속상태로 만든다.
ex) 부모 엔티티를 저장할 때, 자식 엔티티도 함께 저장.
💡연관관계 매핑과 아무 관련이 없다. 연관된 엔티티를 함께 영속화하는 편리함만 제공할 뿐이다.
💡연관된 엔티티가 다른 곳에서도 관리되는 엔티티라면 CASCADE를 쓰면 안된다.
✅코드 예시
@Entity
@Getter
@Setter
public class Parent {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent")
private List<Child> childList = new ArrayList<>();
public void addChild(Child child){
childList.add(child);
child.setParent(this);
}
}
@Entity
@Getter
@Setter
public class Child {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
Parent와 Child를 양방향 매핑하고 childList에 child를 추가하는 메서드가 있다.
✅main 메서드
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();
}
}
여기서 child1, child2, parent를 영속상태로 만들려면 em.persist()를 세번 호출해야하는 귀찮음이 있다.
이때, 영속성 전이를 쓰면 된다.
✅cascade 사용법
//****Parent클래스에 코드 추가
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
//****main메서드 수정 -> parent만 한번 persist
em.persist(parent);
//em.persist(child1);
//em.persist(child2);
✅DB확인
parent만 persist를 해도 영속성 전이(CASCADE)를 했기 때문에 CHILD 테이블에 저장이 잘 된것을 볼 수 있다.
💡parent를 영속성 컨텍스트에서 삭제하면 child들도 모두 삭제된다.
2. 고아 객체 삭제
- 고아 객체 : 부모 엔티티와 연관관계가 끊어진 자식 엔티티
- orphanRemoval = true로 고아 객체를 자동 삭제 할 수 있다.
- 고아 객체 제거는 참조하는 곳이 하나일 때만 사용해야한다.
- 특정 엔티티가 개인 소유할 때 사용한다.
- @OneToOne, @OneToMany만 사용 가능하다.
✅Parent에 코드 추가
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
orphanRemoval = true를 부모 엔티티에 추가한다.
✅main 메서드
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.flush();
em.clear();
Parent findParent = em.find(Parent.class, parent.getId());
findParent.getChildList().remove(0);
tx.commit();
}catch (Exception e){
tx.rollback();
e.printStackTrace(); //예외 출력
}finally {
em.close();
}
}
findParent의 childList에서 0번째 child를 지우는 코드를 추가했다. (연관관계 끊어짐)
✅콘솔 확인
delete
from
Child
where
id=?
findParent와 연관관계가 끊어진 child를 지우는 delete 쿼리가 실행된다.
✅DB 확인
0번째 child가 지워졌다.
💡영속성 전이와 고아 객체, 두 옵션을 모두 활성화하면 부모 엔티티를 통해서 자식 엔티티의 생명주기를 관리할 수 있다.
728x90
'인프런 김영한 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글
JPA 기본 | 데이터 타입(2) - 값 타입 공유와 불변객체 (0) | 2024.07.14 |
---|---|
JPA 기본 | 데이터 타입(1) - 기본 값과 임베디드 값 타입 (0) | 2024.07.14 |
JPA 기본 | 즉시 로딩과 지연 로딩 (0) | 2024.07.13 |
JPA 기본 | 프록시 (즉시 로딩, 지연 로딩을 이해하기 위한) (0) | 2024.07.13 |
JPA 기본 | @MappedSuperclass (0) | 2024.07.10 |