SPRING FRAMEWORK

@Transient 어노테이션 사용해보기

Ambitions 2021. 1. 15. 11:13

최근 개발을 하던 중 특정 테이블에서 조회를 해올때 외래관계가 없는 테이블에서의 값을 조회한 다음 하나의 객체로 클라이언트단으로 전달해주고 싶은 상황이 생겼다. 그래서 최초 조회를 하는 테이블의 엔티티에 변수를 선언해서 SET을 하면 되겠다라는 생각까진 했으나, 한 가지 문제가 있었다.

 

엔티티(모델) 클래스 내에 선언되어 있는 변수는 JPA에서 테이블의 컬럼이 된다는 것인데, 어떻게 하면 컬럼으로 처리되지 않고 무시되게 할 수 있을까하며 찾아본 결과 @Transient라는 어노테이션을 찾을 수 있었다.

대충 공식 문서를 찾아보니 @Transient이 선언되어있는 경우 해당변수(메소드)는 임시데이터로 보고 테이블과 매핑을 하지않는다는 것 같다.

이제 코드로보면 나는 다음과 같이 사용했다.

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
@Entity(name ="test")
@Getter // lombok
public class Test extends JpaEntity<Long> {
    
    @Id
    // id값은 자동생성(auto increment), 유일
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    // 컬럼과 매핑
    @Column(name ="id", nullable=false
    private Long id;
    
    private String text;
    
    //컬럼명과 변수명이 같은경우 사용할 필요없음
    @Column(name="value", nullable=false
    private String value;
    
    // 엔티티매핑에서 무시됨
    @Transient 
    // 클라이언트단에 target이라는 이름으로 전달
    @JsonProperty("target"
    @Setter
    private List<Target> targets = new ArrayList<>();
 
}
cs

다음으로 서비스단에서는 사용한 로직은 대략 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Service
public class Service {
    
    //Autowried 어노테이션을 이용해 의존성주입
    @Autowried
    private TestRepository testrepository;
    
    @Autowried
    private TargetRepository targetrepository;
    
    public void search(long id) {
        Optional<Test> test = testrepository.findById(id);
        // 실개발에선 optional의 값 검증필요
        test.get().setTarget(targetRepository.find..()); 
        
        // 클라이언트로 전달하는 로직
    
    }
    
}
cs

 

위와같은 방법으로 외래관계없이도 따로따로 조회를 통해 한번에 한객체로 클라이언트단으로 전달할 수 있었다.

앞으로 종종 사용하게 될 것 같은데, 꼭 기억해둘 필요가 있어보인다.