JPA @Transient

송재호·2022년 3월 23일
0

@Transient

우선 Transient라는 영단어의 사전적 의미를 생각해보자.
Transient는 사전적 의미로 형용사 "잠깐 머무르는", 명사 "일시적인 사물 또는 사람"이라는 뜻을 가지고 있다.
그렇다면 JPA에서 잠깐 머무르는, 일시적인 사물은 무엇을 의미하는 것일까?

javax.persistence 패키지의 Transient.java에 정의된 내용을 살펴보면 다음과 같다.

Specifies that the property or field is not persistent. It is used to annotate a property or field of an entity class, mapped superclass, or embeddable class.

속성 또는 필드가 영속성으로 관리되지 않음을 지정하며, @Entity, @MappedSuperclass, @Embeddable 어노테이션을 적용한 클래스의 속성 또는 필드에 주석을 다는데 사용된다고 한다.

영속 대상에서 제외 ?

JPA에서 영속 상태에서 제외한다는 의미는 엔티티 매니저에 의해 수행되는 Dirty Checking, CRUD SQL 자동 생성 작업 등의 관리 대상에서 제외된다는 뜻이다. 즉, @Transient가 적용된 필드에 대해 변경 사항을 감지하거나 데이터베이스와 매핑하여 동기화하지 않는다는 것이다.

왜 쓸까 ?

데이터베이스 컬럼으로 관리될 필요는 없으나, 메모리 상에 저장되어 있는 플래그 값을 통해 변경 여부를 저장해 두면 관계가 있는 로직에서 쉽게 분기 처리를 할 수 있을것이라고 생각한다.

예를 들어 Person 엔티티의 name이 변경되었을 때 변경 히스토리를 적재하고 싶거나 관계가 있는 테이블의 name들이 함께 업데이트 되어야 하는 경우에서 응용한다고 생각해보자.

@Getter
@Entity
@Table(name = "person")
public class Person {
	@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "person_id")
    private Long personId;
    
    @Column(name = "name", nullable = false)
    private String name;
    
    @Transient
    @Setter
    private boolean nameUpdated = false;
}

필드 값 변경 전 name과 변경 후 name을 비교하여 다를 때 .setNameUpdated(true)를 한 번 해 둔다면, 메모리 상에서 해당 엔티티가 관리되고 있는 중에는 어디서든 .isNameUpdated()를 통해 name이 전과 달라졌는지 간편하게 알아낼 수 있다. 서비스나 메서드를 분리하여 복잡하게 얽혀있어도 메모리만 유지된다면 언제 어디서든 어떤 분기를 태울 지 결정하기 쉬워진다는 것이다.

또한 직접 테스트 해 본 결과 영속성 컨텍스트의 1차 캐시에 해당 엔티티가 유지되고 있다면 변경된 nameUpdated의 값 또한 그대로 유지되기 때문에 엔티티를 다시 조회해도 문제없이 사용할 수 있다.

profile
식지 않는 감자

0개의 댓글