일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 데이터베이스
- 스프링 시큐리티
- CS
- Spring
- Java
- Container
- HTTP
- spring boot
- 스프링 배치
- CI/CD
- spring batch
- computer science
- spring cloud
- 도커
- Spring Security
- virtualization
- 배포
- vm
- 스프링 부트
- ORM
- 웹 서버
- 영속성 컨텍스트
- 백엔드
- 스프링
- 컨테이너
- JPA
- 가상화
- web server
- mysql
- 자바
- Today
- Total
개발 일기
[Spring Boot] orphanRemoval = true 고아 객체 관리 본문
전 게시글에서 Cascade 영속성 전이 그리고 그중에서도 ALL, REMOVE, PERSIST 타입에 대해 집중적으로 이해해봤다.
개발하다보면 주로 orphanRemoval=true가 쓰이는 것을 종종 볼 수 있는데 이때 orphanRemoval이 어떤 것을 설정하는 것인지 알아보자.
orphanRemoval = true
부모 엔티티와 연관관계가 끊어진 자식 엔티티 를 자동으로 삭제해주는 설정이다.
Content엔티티에서 Comment와 일대다 관계를 맺을 때 아래와 같이 설정한다고 하자.
// Content 엔티티
@OneToMany(mappedBy = "content", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
아래는 ContentService의 예시 메서드이다.
// ContentService
public void removeCommentFromContent(Long contentId, Long commentId) {
Content content = contentRepository.findByIdOrThrow(contentId)
Comment comment = commentRepository.findByIdOrThrow(commentId)
content.removeComment(comment); // content에서 comment를 제거
}
위와같이 특정 게시글에서 그 게시글의 댓글 중 하나를 제거하기 위해서 부모 - 자식 관계를 끊어 놓게되면 그 결과 Comment 엔티티가 데이터베이스에서 DELETE 되는 것을 확인할 수 있다. 즉, 직접 commandRepository.delete(comment)를 하지 않고 자식 엔티티를 부모 엔티티의 컬렉션에서 제거만 하면 DELETE 쿼리가 나가는 것이다.
즉, 참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능이다.
- 참조하는 곳이 하나일 때 사용해야하고
- 특정 엔티티가 개인 소유할 때 사용가능하다.
- @OneToOne, @OneToMany만 가능한 설정이다.
CascadeType.REMOVE와 뭔차이?
똑같은 것은 아니다. 단지 특정 상황에 따라 똑같이 동작할 경우가 있을 뿐이다.
개념적으로 부모를 제거하면 자식은 고아가 된다. 따라서 고 아 객체 제거 기능을 활성화 하면, 부모를 제거할 때 자식도 함께 제거된다.
그렇기 때문에 orphanRemoval = true라는 설정이 부모 객체가 삭제되는 경우 자식이 고아가 되기 때문에 CascadeType.REMOVE처럼 동작는 것이다.
CascadeType.ALL + orphanRemoval = true
영속성 전이와 고아 객체 관리 기능 두개 모두 동시에 킬 수도 있다.
원래 엔티티는 em.persist()로 영속화, em.remove()로 제거하는 것 처럼 스스로 생명 주기를 관리하게 된다.
그러나 제목처럼 두개의 조건을 모두 활성화하게되면 자식 엔티티가 부모 엔티티를 통해서 생명 주기를 관리할 수 있게 된다.
다른 말로 부모 엔티티를 통해서 자식의 생명 주기가 관리되는 것이다. 그렇게되면 자식 객체는 Repository가 필요없다.
이것은 DDD 도메인 주도 설계의 Aggregate Root 개념을 구현할때 유용하다고 한다.
'Back-End > Spring' 카테고리의 다른 글
[Spring Boot] 우아콘2020 - 수십억건에서 QUERYDSL 사용하기 감상문 (2) | 2024.06.04 |
---|---|
[Spring Boot] Entity에서의 올바른 롬복(Lombok) 사용에 있어서 나의 생각 정리 (1) | 2024.06.03 |
[Spring Boot] 연관관계 영속성 전이(CASCADE) - REMOVE, PERSIST, ALL을 중심으로 (1) | 2024.06.03 |
[Spring Boot] Soft Delete시 연관관계 엔티티 처리 (다중 논리 삭제 처리) (0) | 2024.06.02 |
[Spring Boot] Soft Delete(논리 삭제) 도입 - @SQLDelete & @SQLRestriction (0) | 2024.06.02 |