@PrePersist , @Transient 동시 사용시 주의점

차지현·2022년 8월 24일
0

엔티티 클래스에서 영속성 관리대상이 아닌 필드를 추가하고자 할때 @Transient 어노테이션을 이용할수 있습니다. 또, @PrePersist 나 @PreUpdate 어노테이션을 사용하여 엔티티매니저가 persist되거나 merge되는 시점 이전에 이벤트를 발생시킬 수 있습니다.

이 두가지 어노테이션의 속성을 사용해서, 저는 transient 필드값을 update되기 이전에 다른 컬럼들의 값을 채워주고자 했는데, 의도대로 동작하지 않습니다.

구글링을 해보아도 뾰족한 수는 없어 영속성을 구현한 내부 로직의 특성으로 인해 발생하는, 그저 의도대로 동작되지않는 일반적인 현상으로 결론지으려다 아쉬움에 조금 더 테스트 해보았습니다.
먼저, 엔티티 내부에 아래와 같은 두 필드와 메소드를 작성합니다.

@Column(name = "TARGET_FEILD")
private String targetField;

@Transient
private String transientField;

@PreUpdate @PrePersist
public void prePersist(){
	if(StringUtils.hasText(transientField){
    	this.targetField = transientField + "_test";
    }
}

다음으로 transientField value를 "transient"로,
targetField의 value는 null로 생성된 엔티티 객체를, 레포지토리를 통해 save합니다.
신규생성의 경우에는 @PrePersist를 통해 후처리 이벤트 prePersist()가 실행되면서 null 이었던 targetField가 "transient_test" 값을 갖게 됩니다.

하지만 @PreUpdate는 의도와 다르게 동작하는 경우가 있습니다.
스코프 안에서 transientField 값이 null로 초기화되어버립니다.

@PreUpdate @PrePersist
public void prePersist(){
	if(StringUtils.hasText(transientField){ // transientField == null
    	this.targetField = transientField + "_test";
    }
}

영속성에서 한번 detached된 객체를 save할 경우에는 transient 필드의 값이 초기화됩니다.
반대로 영속성에 detached 되지 않고, 계속해서 attched된 상태라면, 의도한대로 "_test" 문자열이 추가됩니다.
따라서 비즈니스 플로우 동작 중에 영속성을 끊기는 경위가 있는지 먼저 파악해야합니다.

profile
의 가상메모리 공간📂

0개의 댓글