Back-End/Study

순환참조 해결 @JsonIgnore, @JsonManagedReference, @JsonBackReference

yeonx 2022. 7. 29. 05:33
728x90

사용 방법

일단 이를 사용하기 위해서는 build.gradle 설정이 필요함.

다음을 dependencied에 추가

 


순환 참조 

 

JPA는 디폴트로 매핑된 데이터에 대해 FetchType.LAZY (게으른 불러오기)를 사용함.

예를 들어, User라는 Entity와 Account라는 Entity가 서로 양방향 참조 (1:N)을 하고 있다고 하자.

 

public class User{
	@Id
    private Long user_id;
    
    ...
    
    @OneToMany(mappedBy = "user")
    private List<Account> accounts;
}
public class Account{
	@Id
    private long id;
    
    ...
    
    @ManyToOne
    @JoinColumn(name="user_id")
    private User user;
}

Controller를 통해 Account Entity를 Response로 내보내고 브라우저에 json 형태로 뿌려주기 위해서 Account entity가 참조하고 있는 User entity도 함께 불러오게 된다. 하지만 여기서 문제가 발생한다.

User enetity는 다시 Account entity를 참조하기 때문에 또 Account entity를 불러오는 것이다. Repository에서는 Account entity 하나를 return 하더라도 Controller를 통해 Response 되어 json으로 표시될 때는 이렇게 두 개의 entity가 계속해서 서로를 불러오면서 페이지 가득 똑같은 데이터가 중복되어 노출된 것이다.

 

Solution

1. @JsonIgnore : 이를 붙이면 json 데이터에 해당 프로퍼티는 null로 들어가게 된다. 즉, 데이터에 아예 포함되지 않는다. 

2. @JsonManagedReference, @JsonBackReference : 이 두 어노테이션은 순환참조를 방어하기 위한 어노테이션이다. 부모 클래스 (User entity)에  @JsonManagedReference를, 자식 클래스 측(Account entity)에 @JsonBackReferece 어노테이션을 추가해주면 된다.

3. DTO 사용 : 위와 같은 상황이 발생하게 된 주 원인은 '양방향 맵핑'이기도 하지만, 더 정확하게는 entity 자체를 reponse로 return 하는 데에 있다. entity자체를 return하지 말고, dto 객체를 만들어 필요한 데이터만 옮겨 담아 client로 리턴하면 순환 참조와 관련된 문제는 애초에 방어할 수 있다.

 

 

참고 : https://m.blog.naver.com/writer0713/221587351970

'Back-End > Study' 카테고리의 다른 글

DAO와 Repository 차이  (0) 2022.08.10
Lombok 라이브러리 어노테이션  (0) 2022.08.04
JPAQueryFactory  (0) 2022.08.01
유효성 검사 - @NotNull @NotEmpty @NotBlank  (0) 2022.07.30
BaseTimeEntity 적용  (0) 2022.07.29