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

기본 생성자가 없다고요? Cannot construct instance of 에러 원인과 1초 해결법

by 데브프리 2026. 7. 2.

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

 

프론트엔드에서 백엔드로 예쁜 JSON 데이터를 담아 POST 요청을 보냈을 때, 분명 데이터 오타도 없고 주소도 맞는데 백엔드 콘솔창에 기나긴 에러가 도배되며 400 에러가 뜨는 경우가 있습니다.

 

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of 'com.devfree.dto.UserRequestDto' (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)

또는 no Creators, like default construct, exist

 

이름도 길고 복잡한 이 에러 메시지, 읽기만 해도 머리가 아파옵니다. 결론부터 말씀드리면 이 에러는 "네가 만든 DTO 클래스에 기본 생성자(빈 뼈대)가 없어서 객체를 조립할 수가 없어!"라며 Jackson(잭슨) 라이브러리가 비명을 지르는 것입니다.

 

오늘은 백엔드 개발자들이 숨 쉬듯이 마주치는 이 '기본 생성자 누락 에러'의 원인을 직관적인 비유로 알아보고, 단 1초 만에 해결하는 방법을 완벽하게 정리해 드리겠습니다!

 

1. Cannot construct instance 에러, 도대체 넌 누구냐? (프라모델 빈 뼈대 비유)

스프링 부트에서 클라이언트가 보낸 JSON 데이터({"name": "데브프리"})를 자바 객체(DTO)로 변환(역직렬화)해 주는 일은 Jackson(잭슨)이라는 직원이 담당합니다.

스프링 부트 Jackson 역직렬화 기본 생성자 에러 비유
Jackson은 데이터를 채워 넣기 전에 먼저 '아무것도 들어있지 않은 빈 객체(기본 생성자)'를 하나 만들어야 하는데, 이 뼈대가 없으면 작업을 시작조차 하지 못합니다.

일상생활의 프라모델 조립에 비유해 볼까요?

Jackson 직원은 프론트엔드가 보낸 택배(JSON)에서 부품들을 꺼냈습니다. 이제 이 부품을 로봇에 끼워 맞춰야 하는데, 부품을 붙일 '기본 뼈대(빈 객체)'가 없는 상황입니다.

 

자바에서 클래스를 만들 때, 우리가 직접 매개변수가 있는 생성자(예: public UserDto(String name) {...})를 하나라도 만들어두면, 자바는 기본적으로 제공하던 '아무것도 없는 빈 생성자(Default Constructor)'를 뺏어가 버립니다.

빈 뼈대가 사라졌으니 Jackson 직원은 "조립을 시작할 뼈대(no Creators)가 존재하지 않아 객체를 생성(construct instance)할 수 없어!"라며 에러를 던지게 되는 것입니다.

 

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

해결 원리는 너무나도 간단합니다. 깐깐한 Jackson 직원이 작업을 시작할 수 있도록, 아무런 조건도 없는 '빈 뼈대(기본 생성자)'를 하나 다시 만들어주면 됩니다.

스프링 부트 NoArgsConstructor 기본 생성자 해결
클래스에 기본 생성자를 추가해 주면 Jackson이 일단 빈 객체를 생성한 뒤, 내부 기능을 이용해 데이터를 쏙쏙 채워 넣을 수 있습니다.

스프링 부트 환경에서 이 에러를 해결하는 가장 대표적인 방법 2가지를 소개합니다.

방법 ①: 롬복(Lombok) @NoArgsConstructor 사용 (가장 추천)

현업에서 가장 많이, 그리고 가장 널리 사용하는 방법입니다. 에러가 난 DTO 클래스 상단에 @NoArgsConstructor 어노테이션 딱 한 줄만 추가해 줍니다.

Java
 
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
// 💡 @NoArgsConstructor를 붙이면 파라미터가 없는 기본 생성자(빈 뼈대)가 자동으로 만들어집니다!
@NoArgsConstructor 
public class UserRequestDto {
    
    private String username;
    private int age;

    // 개발자가 직접 만든 생성자 (이것 때문에 기본 생성자가 사라졌던 것!)
    public UserRequestDto(String username, int age) {
        this.username = username;
        this.age = age;
    }
}

어노테이션 하나만 붙여주면 롬복이 내부적으로 보이지 않는 public UserRequestDto() {}를 만들어주어 에러가 즉시 해결됩니다. (접근 제어자를 안전하게 하려면 @NoArgsConstructor(access = AccessLevel.PROTECTED)를 사용하는 것도 실무 꿀팁입니다!)

방법 ②: 수동으로 기본 생성자 작성하기

만약 프로젝트에 롬복(Lombok)이 적용되어 있지 않다면, 직접 코드로 텅 빈 생성자를 적어주시면 됩니다.

Java
 
public class UserRequestDto {
    
    private String username;
    private int age;

    // 💡 잭슨(Jackson) 라이브러리를 위한 빈 뼈대 수동 제공
    public UserRequestDto() {
    }

    public UserRequestDto(String username, int age) {
        this.username = username;
        this.age = age;
    }
}

이렇게 빈 뼈대를 제공해 주면, Jackson은 일단 빈 UserRequestDto를 하나 생성한 뒤 리플렉션(Reflection)이나 Getter/Setter를 이용해 찰떡같이 데이터를 채워 넣어 줍니다.

 

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

Cannot construct instance of 에러가 발생했다면 당황하지 말고 아래 3가지를 체크하세요.

  1. 에러가 난 클래스 확인: 에러 로그 첫 줄에 Cannot construct instance of 'com.devfree.dto.OOODto' 라고 친절하게 적혀있는 객체 파일을 엽니다. (주로 @RequestBody로 받는 객체입니다.)
  2. 기본 생성자 존재 여부: 해당 클래스 상단에 @NoArgsConstructor가 있는지, 혹은 클래스 내부에 아무 매개변수도 받지 않는 텅 빈 생성자가 있는지 확인합니다.
  3. Builder 패턴 사용 시 주의: 롬복의 @Builder나 @AllArgsConstructor를 클래스에 달아두면 기본 생성자가 사라집니다. 따라서 이 어노테이션들을 쓸 때는 반드시 @NoArgsConstructor를 세트로 함께 달아주는 습관을 들여야 합니다.

 

마무리

JSON 데이터를 객체로 변환하다가 에러가 났을 때, 초보 개발자분들은 보통 "프론트엔드에서 보낸 데이터 타입이 틀렸나?" 하고 데이터 값부터 의심하곤 합니다.

 

하지만 이 no Creators 에러는 데이터 값의 문제가 아니라 단순히 "그릇을 만들 틀이 없다"는 설계도 문제일 뿐입니다. 객체의 생성 원리와 Jackson의 동작 방식을 살짝만 이해하고 나면, 1초 만에 어노테이션을 붙이고 커피를 마시러 갈 수 있는 아주 쉬운 에러입니다.

 

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

 

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