본문 바로가기
💻 트러블슈팅 (에러 해결)

분명 데이터는 있는데 500 에러? No serializer found for class 원인과 해결법

by 데브프리 2026. 6. 27.

안녕하세요, 여러분의 든든한 IT 길잡이 데브프리입니다.

 

스프링 부트(Spring Boot)로 게시판이나 API를 만들다 보면, 데이터베이스에서 값을 완벽하게 잘 가져왔는데도 불구하고 화면에 데이터를 뿌려주지 못하고 500 Internal Server Error를 뱉어내는 황당한 상황을 마주하게 됩니다.

 

콘솔창을 열어보면 엄청나게 긴 에러 메시지가 우리를 반겨줍니다. com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class ... and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

 

DB 쿼리도 맞고 로직도 완벽한데 도대체 왜 데이터를 보여주지 못하는 걸까요? 오늘은 프론트엔드로 데이터를 넘길 때 빈번하게 발생하는 'Jackson 직렬화(Serialization) 에러'의 원인을 아주 직관적으로 알아보고, 단 1초 만에 해결하는 2가지 방법을 완벽하게 정리해 드리겠습니다!

 

1. No serializer found 에러, 도대체 넌 누구냐? (블랙박스 포장 비유)

스프링 부트는 우리가 자바 객체(Object)를 반환하면, 프론트엔드가 알아먹을 수 있도록 이를 JSON 형태({"이름": "데브프리"})로 예쁘게 포장해서 보내줍니다. 이때 포장을 전담하는 기본 라이브러리가 바로 Jackson(잭슨)입니다.

스프링 부트 Jackson 직렬화 에러 원인 비유
Jackson은 자바 객체 내부를 들여다보고 데이터를 꺼내야 하는데, 내용물을 볼 수 있는 '창문(Getter)'이 없으면 에러를 발생시킵니다.

Jackson 직원은 우리가 넘겨준 자바 객체의 내부 데이터를 하나씩 꺼내서 JSON 상자에 옮겨 담습니다. 그런데 만약 우리가 객체에 접근할 수 있는 '창문'을 만들어두지 않았다면 어떻게 될까요?

 

자바에서 클래스의 변수들은 보통 private으로 꽁꽁 숨겨져 있습니다. Jackson 직원은 이 까만 블랙박스 안을 들여다볼 권한이 없으니, "안에 뭐가 들었는지 안 보여서 포장을 못 하겠어!!"라며 파업을 선언해 버립니다. 이것이 바로 No serializer found for class (이 클래스를 변환할 직렬화 도구를 찾을 수 없다) 에러의 진짜 의미입니다.

 

2. 스프링 부트에서 이 에러를 해결하는 2가지 방법

해결 원리는 너무나도 간단합니다. 까만 블랙박스에 Jackson 직원이 안을 들여다보고 데이터를 꺼내갈 수 있도록 투명한 창문(Getter)을 뚫어주기만 하면 됩니다.

스프링 부트 Getter 추가 JSON 변환 해결
객체에 Getter를 추가해 주면 Jackson이 데이터를 무사히 읽어와 JSON 형태로 완벽하게 변환해 줍니다.

스프링 부트에서는 이 창문을 만들어주는 2가지 확실한 방법이 있습니다.

방법 ①: 롬복(Lombok) @Getter 어노테이션 사용 (가장 추천)

현업에서 가장 많이, 그리고 가장 쉽게 사용하는 방법입니다. 프론트엔드로 반환하려는 DTO(Data Transfer Object)나 Entity 클래스 상단에 @Getter 어노테이션 딱 한 줄만 추가해 줍니다.

Java
 
import lombok.Getter;

// 💡 @Getter를 붙이면 보이지 않던 private 변수들에 접근할 수 있는 창문이 열립니다!
@Getter 
public class BoardResponseDto {
    
    private Long id;
    private String title;
    private String content;

    public BoardResponseDto(Long id, String title, String content) {
        this.id = id;
        this.title = title;
        this.content = content;
    }
}

@Getter를 붙이는 순간 롬복이 내부적으로 getId(), getTitle() 등의 메서드를 자동으로 만들어주며, Jackson은 이를 통해 데이터를 쏙쏙 뽑아 JSON으로 변환합니다.

방법 ②: 수동으로 Getter 메서드 작성하기

만약 프로젝트에 롬복(Lombok)이 설치되어 있지 않거나, 특정 변수만 선택적으로 노출하고 싶다면 직접 public 접근 제어자를 가진 Getter 메서드를 작성해 주면 됩니다. IDE의 단축키(Alt + Insert 또는 Cmd + N)를 사용하면 1초 만에 만들 수 있습니다.

Java
 
public class BoardResponseDto {
    
    private Long id;
    private String title;

    public BoardResponseDto(Long id, String title) {
        this.id = id;
        this.title = title;
    }

    // 💡 수동으로 창문(Getter)을 만들어 Jackson이 접근할 수 있게 허용합니다.
    public Long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }
}

이렇게 Getter가 존재하는 클래스 객체를 컨트롤러에서 반환하면, 500 에러 대신 아름답게 파싱된 JSON 데이터를 브라우저에서 만날 수 있습니다.

 

3. 요약: 트러블슈팅 체크리스트

No serializer found for class 에러가 발생했다면 당황하지 말고 아래 3가지를 체크하세요.

  1. 반환(Return) 객체 확인: 컨트롤러에서 프론트엔드나 클라이언트로 Return 하고 있는 객체(DTO, Entity 등)가 무엇인지 확인합니다.
  2. Getter 존재 여부: 해당 객체의 클래스 파일을 열어 상단에 @Getter 어노테이션이 붙어 있는지, 혹은 하단에 get...() 메서드가 구현되어 있는지 확인합니다.
  3. 접근 제어자 확인: Getter 메서드를 직접 만들었다면 실수로 private으로 만들지 않았는지 확인합니다. 반드시 외부에서 접근 가능한 public이어야 합니다.

 

마무리

컨트롤러와 서비스 로직을 완벽하게 짰는데 마지막 출력 단계에서 에러가 나면 정말 허탈하죠.

 

하지만 이 에러는 컴퓨터가 고장 난 것이 아니라, 자바의 훌륭한 객체지향 보안 원칙(은닉화) 때문에 외부 라이브러리인 Jackson이 여러분의 소중한 데이터에 함부로 접근하지 못해서 생긴 일종의 '보안 출입 통제' 현상입니다. 접근 권한(Getter)만 부여해주면 모든 문제가 눈 녹듯 사라집니다.

 

오늘 준비한 트러블슈팅 가이드가 여러분의 붉은 에러 창을 깨끗하게 지워주었기를 바랍니다. 오류를 고친 경험은 여러분의 가장 큰 자산이 됩니다. 막히는 에러가 있다면 언제든 댓글로 남겨주세요.

 

지금까지 데브프리였습니다. 감사합니다!