본문 바로가기
기억 할 것들

Jpa 영속성전이(Cascade) 및 고아 객체

by jay-choe 2021. 9. 26.

먼저 기존에 서버에서 외래키 관련해서 에러가 났었다.

대략적인 내용은, 외래키로 묶여있는 두 테이블에서 하나의 엔티티를 삭제할 때, 다른 엔티티가 참조하는 값이 없어져서 나오는 오류였는데

(참조무결성) 예전에 정처기공부할때 Cascade 제약조건이 생각나서, 이전에 깃헙에서 여러 코드를 볼때, 연관관계에 cascade

를 옵션으로 달아주던게 생각나서 공부를 해봤다. 

 

내용은 인프런 강의(자바 ORM 표준 JPA 프로그래밍 - 기본편)을 듣고 정리해봤다.

 

특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 같이 영속 상태로 만들고 싶을 때

(예를들어 One to Many 관계에서 One 을 저장 할 때, Many들도 같이 저장하고 싶을 때 사용)

 

예를들어 Parent, Child 엔티티가 있고,

둘의 관계가 OneToMany라면

Parent엔티티에서 Child의 부분은 List<Child>로 되어있을 것이다.

 

여기서 Parent를 저장하려 할 때 이렇게 하고싶은 경우가 있을것이다

Parent와 연관된 Child들을 같이 저장하려고 하는 경우.

 

원래 로직이라면, Child를 따로 하나씩 저장(persist)하고, Parent를 따로 저장시켜 주어야 하지만 이는 분명 번거로운 작업이다.

그래서 @OneToMany 어노테이션 안에  cascade = CascadeType을 지정시켜주면,

안에있는 List에 Child를 추가해줘도, 같이 영속이 된다.

 

CascadeType에는 ALL(모두), REMOVE(삭제시), PERSIST(영속시).. 등등이 있는데, 실제로 접할것 같은건 삭제, 영속 일 것 같다.

 

물론 쿼리가 나가는 것 (Insert)은 똑같다. (연관 관계와 아무런 연관이 없으며 ,단지 편리함을 위한 것)

 

추가적으로 고아 객체 제거라는 개념 (Orphan Remove)도 옵션으로 줄 수 있는데,

 

이는 Parent엔티티에서 , Child 리스트의 내용을 지우게 되면, 자동적으로 Child 엔티티가 지워지는 것을 의미한다.

조금 생각해보니, Parent에서 Child중 하나를 없앴는데 Delete 쿼리가 나가지 않는다면, 실제 Parent가 제거한 자식(말이 좀.. 이상하네요) 은 부모를 참조하지만 부모는 참조하지 않는 괴이한 현상이.. 발생한다. 혹은 외래키 참조제약이 걸려있다면 참조무결성 제약조건을 위반하게 됩니다. 그래서 OrphanRemoval=true 라는 옵션을 연관관계 어노테이션 안에 주면, Parent에서 제거를 하더라도 Delete 쿼리가 나가서 부모가 없는.. 자식이 존재하지 않도록 유지가 됩니다.

+ 부모의 입장에서 제거를 하는 것이라 @OneToOne, @OneToMany 관계에서만 적용이 가능합니다.

 

역시 공부는 실제 필요할 때 하는게 최고인 것 같다!

'기억 할 것들' 카테고리의 다른 글

301 vs 302 redirect  (0) 2022.02.19
X-Forwarded_FOR(XFF)  (0) 2021.09.13
쉘에서 유저 변경하기  (0) 2021.07.31