Jackson 역직렬화

0_0_yoon·2023년 11월 15일
0

문제상황

인수테스트에서 응답을 역직렬화하는 과정에서 아래와 같은 예외가 발생했다.
2023-11-15 20:35:45.875 WARN 54421 --- [o-auto-1-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Cannot invoke "java.lang.Long.longValue()" because "this.tableGroupId" is null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Cannot invoke "java.lang.Long.longValue()" because "this.tableGroupId" is null (through reference chain: kitchenpos.dto.response.TableGroupResponse["orderTables"]->java.util.ArrayList[0]->kitchenpos.dto.response.OrderTableResponse["tableGroupId"])]

문제가 된 dto 의 코드.

public class OrderTableResponse {

    private long id;
    private Long tableGroupId;
    private int numberOfGuests;
    private boolean empty;

    // 생략

    public long getTableGroupId() {
        return this.tableGroupId;
    }
}

원인

Jackson 이 직렬화 및 역직렬화하는 과정에 대한 이해부족.
Jackson 은 클래스 정보를 조사해서(클래스 파일의 멤버 필드, getter setter 메서드, 생성자 등) 프로퍼티 정보를 저장한다. 그리고 이를 기반으로 직렬화 및 역직렬화 한다. 이때 접근제어자가 public 인 경우에만 프로퍼티 정보를 저장하도록 되어있다. 따라서 문제가 발생한 dto 경우 long 타입의 tableGroupId 이름을 가진 프로퍼티 정보가 저장됨을 예상할 수 있다. 여기에 null 값 할당을 시도했기 때문에 예외가 발생한 것이다.

해결

별다른 코드를 추가하지 않고 해결하는 방법은 두 가지가 있다.
첫 번째 멤버 필드의 접근제어자를 public 으로 넓힌다.
두 번째 getter 메서드의 반환 타입을 Long 타입으로 수정한다.
멤버 필드의 외부 접근을 허용하면 부수 작용이 발생할 수 있으므로 두 번째 해결 방법을 선택했다.

public class OrderTableResponse {

    private long id;
    private Long tableGroupId;
    private int numberOfGuests;
    private boolean empty;

    // 생략

    public Long getTableGroupId() {
        return this.tableGroupId;
    }
}

참고: https://velog.io/@0_0_yoon/Jackson-ObjectMapper-%EC%84%A4%EC%A0%95-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0#%ED%95%B4%EA%B2%B0-%EA%B3%BC%EC%A0%95

profile
꾸준하게 쌓아가자

0개의 댓글