Programming/Spring

[Spring JPA] Casacade(영속성 전이), 고아제거속성

주죵 2022. 6. 22. 22:44
728x90
반응형

영속성 전이는 연관관계에 있는 entity에 대하여, 영속성을 전파시키는 것이다.

예시를 보며 이해보자

 

A entity와 B entity가 OnetoOne 연관관계가 있다고 할때,

A a = new A();
B b = new b();

a.setB(b)

aRepository.save(a);

이런 코드가 있다면 오류가 발생할것이다. 왜냐면 a, b가 모두 비영속상태인 상태에서 onetoone 관계를 맺고 저장을 시켜버리기 때문. 실제 DB나 영속성 컨텍스트엔 a,b가 존재하지 않는상태이므로 연관관계를 맺어 저장시키면 transient한 object를 저장해버린다며 오류메시지를 던진다

 

이때 아래처럼 A entity내의 B에 CascadeType= PERSIST 를 지정해버리면, A의 persist(저장, insert)가 일어날때 연관관계에 있는 B도 insert가 일어나며(영속성의 전이) 오류없이 OnetoOne 연관관계를 맺는 a, b가 모두 저장되게 된다.

@Data
@Entity
public class A {

	@Id
	private long id;
    
	@OnetoOne(cascade =CasacadeType.PERSIST)
    @JoinColum(name = "b_id")
	private B b;
    
}

 

즉 B repository의 호출을 통한 B의 조작 없이 연관관계에 있는 A 호출하여, 영속성 전이를 일으켜 B를 조작하는것이다.

문제! 위에서 이번엔 이미 저장된 a를 a repository에서 다시꺼내서 b의 멤버를 새로 set하면(update) 어떻게될까?

정답은 바뀌지 않는다! 왜냐면 cascadeType 범위를 PERSIST(insert) 까지 해놨기 떄문, casacadeType에 MERGE(update)를 추가해줘야 위에 말한 동작까지 수행이 가능해진다.

(이외의 Casacade 관련된 옵션은 추가로 찾아보며 공부해보자.)

 

 

이번에는 DELETE가 되는 상황을 고려해보자

OneToMany (aㅌb) 로 지정된 객체가 있다. a에는 b와 연결된 foreign key가 존재할것이다

이때 a의 foreign key에 null을 넣어버리게 된다면 어떻게될까?

- 당연히 a에 저장되어있던 b와의 릴레이션이 제거되고, 연관관계가 사라질것이다

- 그러나 이런경우에는 연관관계를 잃어 무쓸모가 되버린 b는 사라지지 않고 그대로 db에 남아있을것이다

- 아니면 a자체를 delete해버리면 어떨까? 여전히 b는 남아있을것이다

- 이때 연관관계를 잃어버린 b를 고아객체라고함

 

그렇다면 연관관계를 위처럼 지우거나 끊어버릴때 관련된 값들도 함께 사라지게 하고싶다면 어떡할까? 두가지 방법이 있다.

1) cascade 옵션을 ALL로 거는등과 같이 영속성 전이로 삭제될때 같이 삭제되도록 한다

  - 이런경우에 단순 연관관계만 끊는(릴레이션 key에 null 주입) 것이므로 고아객체 b가 사라지진 않는다. remove 이벤트가 발생하는것은 아니므로 영속성 전이가 일어나진 않기때문

2) orphanRemoval 옵션을 true로 설정

  - 연관관계가 끊어질때도 필요없어진 고아객체를 삭제하도록 함

 

 

흠.. 연관관계가 끊어진 고아객체라도 db에 저장은 하고싶은데..... 더이상 조회하거나 사용하고싶진 않아,,!  라고하는 경우도 있을거다. 이때는 상위 객체의 삭제여부를 확인하는 플래그컬럼(boolean deleted 이런식)을 사용하면 될것이다. 그러나 이렇게 사용해버린다면 모든 쿼리에 deleted=false 라는 조건이 들어가야할것이다

- 이때  entity class단위에 @Where 어노테이션을 사용한다. 

- @Where(clause = "deleted = false") 라는 어노테이션을 달아준다면 jpa에서 기본적으로 해당 조건을 자동으로 추가하여 조회가능

 

 

 

 

 

 

 

728x90

'Programming > Spring' 카테고리의 다른 글

[Spring JPA] Transactional Manager  (0) 2022.05.12
[Spring JPA] Entity lifecycle  (0) 2022.04.25
[Spring JPA] 영속성 컨텍스트  (0) 2022.04.24
SpringData JPA 기초  (0) 2022.02.23
[Spring boot] Spring Boot란  (0) 2021.06.20