직렬화란? (serialization)
쉬운 의미로는, 객체나 데이터를 다른 환경에서도 사용할 수 있는 형태로 바꾸는 것
네트워크를 통해 다른 곳으로 전송할 수 있는 형식이나, 파일에 저장할 수 있는 형식으로 객체를 변환하는 것
JSON 직렬화?
객체와 JSON 포맷을 상호 변환하는 기능이다. 쉽게말해서 Object를 JSON으로 바꾸는 것
게시판 만들기, AJAX로 댓글 다는 기능 구현 진행중에 마주한 문제때문에 직렬화를 학습하게 되었다.
순환참조 문제 발생
내가 마주한 문제는 두개의 엔티티 클래스(Question과 Anawer)에서 서로의 컬럼(Question의 answerList, Answer의 question)을 조인한 상태에서 양쪽 필드에 @JsonProPerty를 달아주었다. 브라우저에서 실행시켜보니 이런 에러가 발생했다.
Could not write JSON: Infinite recursion (StackOverflowError);
검색을 해보니 JPA 연관관계에서 양방향 매핑을 해서 발생한 것이 원인이였다. 컨트롤러 단에서 JSON타입을 변환하는 도중에 엔티티의 필드가 다른 엔티티를 참조하고, 그 엔티티 클래스의 필드가 또 엔티티를 참조하고.. 이런식으로 무한루프가 발생한 것이다.
각각의 필드에 @JsonManagedReference와 @JsonBackReference 어노테이션을 붙여주었더니 해당 에러는 사라졌다. 하지만 또다른 문제를 마주했다. 브라우저에서 해당기능을 테스트해보니 브라우저 콘솔에 이런 에러가 발생했다.
Uncaught TypeError: Cannot read property 'id' of undefined
알아보니, @JsonManagedReference와 @JsonBackReference을 잘못 달아줘서 직렬화가 안된것이 원인이였다. 블로그를 보고 나름 알맞다고 생각하는 곳에 달아줬다고 생각했는데 직렬화에 대한 개념이 없어서 잘못 달게 되었다.
@JsonManagedReference : 양방향 관계에서 정방향 참조할 변수에 추가하면 직렬화에 포함된다.
@JsonBackReference : 양방향 관계에서 역방향 참조로, 추가하면 직렬화에서 제외된다.
나의 경우에는 question이 부모이고, answer가 child 인데 @JsonBackReference는 child (answerList)에 다는 것이다.
https://docs.unity.cn/kr/2018.4/Manual/JSONSerialization.html