Jackson em Kotlin: como corrigir o erro "No Creators, like default construct, exist"

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que seu código Kotlin de repente "quebra" o Jackson?



Você já escreveu em Kotlin um data class bonito e conciso, adicionou alguns campos, executou a desserialização JSON via Jackson — e de repente recebeu um erro longo e assustador? Familiar? Se sim, você não está sozinho. O erro "No Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator" é uma das perguntas mais populares no Stack Overflow (milhares de visualizações!) entre desenvolvedores que estão migrando de Java para Kotlin.



Neste artigo, não vamos apenas traduzir o texto do erro. Vamos analisá-lo "sob o microscópio": por que ele ocorre, como reproduzi-lo e, o mais importante, como se livrar dele de uma vez por todas. Você receberá não apenas teoria, mas também soluções prontas e testadas com código em Kotlin. Vamos lá!



O que esse erro significa? Em palavras simples



Vamos imaginar que o Jackson é um "construtor" que precisa montar um objeto da sua classe a partir dos blocos JSON. Para construir uma casa, o construtor precisa de uma planta clara (construtor) ou pelo menos de um conjunto de paredes prontas (campos).



O erro "No Creators, like default construct, exist" literalmente diz: "Prezado Jackson, não consigo criar um objeto desta classe porque ela não tem um construtor padrão (sem parâmetros) e não sei como montá-lo a partir dos campos JSON fornecidos!"



Em Java, é simples: se você não escreveu nenhum construtor, o compilador cria gentilmente um construtor vazio padrão. O Jackson o vê e o utiliza alegremente. Em Kotlin, no entanto, se você define um data class com parâmetros no construtor, o construtor sem parâmetros não é criado automaticamente. E o Jackson, por padrão, procura exatamente por ele.



Reproduzindo o problema: código que gerará o erro



Vamos escrever um exemplo simples que certamente causará esse erro. Imagine que temos uma classe de usuário:



import com.fasterxml.jackson.databind.ObjectMapperimport com.fasterxml.jackson.module.kotlin.readValueimport com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

// ATENÇÃO: Este código causará um erro!data class User(val name: String, val age: Int)

fun main() { val mapper: ObjectMapper = jacksonObjectMapper() val json = """{"name": "Alexei", "age": 30}"""

// Tentando desserializar JSON para um objeto User val user: User = mapper.readValue(json) println(user)}


Execute este código e você obterá a famosa exceção:



com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `User` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (String)"{"name": "Alexei", "age": 30}"; line: 1, column: 2]


Aí está, nossa "estrela" do Stack Overflow! Por que isso aconteceu? Porque data class User(val name: String, val age: Int) não tem um construtor sem parâmetros. Todos os seus campos são declarados no construtor primário e são obrigatórios (val). O Jackson não pode criar um User sem saber quais valores passar para name e age, e sem ter dicas na forma de setters.



3 formas de corrigir o erro (do simples ao correto)



A boa notícia: existem várias soluções. A escolha depende de quanto você deseja controlar o processo e qual código considera "limpo".



Forma 1: A mais simples (mas não para puristas do Kotlin)



Adicionar um construtor sem parâmetros manualmente. Em Kotlin, isso é feito definindo valores padrão para todos os campos.



import com.fasterxml.jackson.databind.ObjectMapperimport com.fasterxml.jackson.module.kotlin.readValueimport com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

// Sim

Blogs

Book Recommendations