카테고리 없음

순환 참조 해결: Jackson 라이브러리의 @JsonManagedReference와 @JsonBackReference 사용하기

초코송이냠 2024. 7. 28. 00:08

개발을 진행하면서 순환 참조 문제는 흔히 발생할 수 있는 이슈 중 하나라고 한다. 특히 JSON 직렬화 과정에서 순환 참조가 발생하면 스택 오버플로우 에러가 발생하거나 직렬화가 제대로 이루어지지 않는 경우가 많다고 한다. 나 역시 지난 프로젝트에서 이와 같은 문제를 겪어보았기에 이번 글에서는 Jackson 라이브러리의 @JsonManagedReference와 @JsonBackReference 어노테이션을 사용하여 순환 참조 문제를 해결하는 방법에 대해 알아보겠다.

 

순환 참조 문제란?

순환 참조(Circular Reference)란 두 객체가 서로를 참조하는 경우를 말한다. 예를 들어, Parent 객체가 Child 객체를 참조하고, Child 객체가 다시 Parent 객체를 참조하는 경우이다. 이러한 구조는 다음과 같은 코드로 표현될 수 있다.

public class Parent {
    private Long id;
    private String name;
    private Child child;
    // getters and setters
}

public class Child {
    private Long id;
    private String name;
    private Parent parent;
    // getters and setters
}

이러한 구조에서 Jackson을 사용하여 JSON 직렬화를 시도하면, Parent와 Child가 서로를 참조하면서 무한 루프에 빠지게 된다.

Jackson 라이브러리의 @JsonManagedReference와 @JsonBackReference

Jackson 라이브러리는 순환 참조 문제를 해결하기 위한 여러 가지 방법을 제공한다. 그중에서 가장 간단하고 직관적인 방법은 @JsonManagedReference와 @JsonBackReference 어노테이션을 사용하는 것이다.

  • @JsonManagedReference: 직렬화 과정에서 이 어노테이션이 붙은 필드를 포함한다.
  • @JsonBackReference: 직렬화 과정에서 이 어노테이션이 붙은 필드를 무시한다.

위의 예제를 수정하여 순환 참조 문제를 해결할 수 있다.

public class Parent {
    private Long id;
    private String name;

    @JsonManagedReference
    private Child child;

    // getters and setters
}

public class Child {
    private Long id;
    private String name;

    @JsonBackReference
    private Parent parent;

    // getters and setters
}

이렇게 어노테이션을 추가하면, Jackson은 Parent 객체를 직렬화할 때 Child 객체를 포함하고, Child 객체를 직렬화할 때는 Parent 객체를 무시한다. 이를 통해 무한 루프를 방지할 수 있다.

예제 코드

아래는 간단한 예제 코드이다. Parent와 Child 객체를 생성하고 Jackson을 사용하여 JSON으로 직렬화해 보겠다.

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) {
        try {
            ObjectMapper mapper = new ObjectMapper();

            Parent parent = new Parent();
            parent.setId(1L);
            parent.setName("Parent");

            Child child = new Child();
            child.setId(1L);
            child.setName("Child");
            child.setParent(parent);

            parent.setChild(child);

            String json = mapper.writeValueAsString(parent);
            System.out.println(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

위 코드에서 ObjectMapper를 사용하여 Parent 객체를 JSON으로 직렬화하면 순환 참조 문제가 발생하지 않고 정상적으로 직렬화된 결과를 얻을 수 있다.

결론

순환 참조 문제는 개발 과정에서 흔히 발생할 수 있는 이슈이지만, Jackson 라이브러리의 @JsonManagedReference와 @JsonBackReference 어노테이션을 사용하면 간단하게 해결할 수 있다. 나 역시 프로젝트에서 같은 방법으로 해결했다. 이번 글에서는 이러한 어노테이션을 사용하여 순환 참조 문제를 해결하는 방법에 대해 알아보았다. 여러분의 프로젝트에서도 순환 참조 문제를 겪고 있다면, 이 방법을 사용해 보길 바란다!