50 votes

ObjectMapper ne peut pas désérialiser sans constructeur par défaut après la mise à niveau vers Spring Boot 2

J'ai les DTOs suivants :

@Value
public class PracticeResults {
    @NotNull
    Map<Long, Boolean> wordAnswers;
}

@Value
public class ProfileMetaDto {

    @NotEmpty
    String name;
    @Email
    String email;
    @Size(min = 5)
    String password;
}

@Value est une annotation Lombok qui génère un constructeur. Ce qui signifie que cette classe n'a pas de constructeur sans argument.

J'ai utilisé Spring Boot 1.4.3.RELEASE et ObjectMapper a été capable de désérialiser un tel objet à partir de JSON.

Après la mise à niveau vers Spring Boot 2.0.0.M7, je reçois l'exception suivante :

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of PracticeResults (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

La version de Jackson utilisée dans Spring Boot 1.4.3 est la suivante 2.8.10 et pour Spring Boot 2.0.0.M7 c'est 2.9.2 .

J'ai essayé de chercher ce problème sur Google mais je n'ai trouvé que des solutions avec @JsonCreator o @JsonProperty .

Alors, pourquoi cela fonctionne-t-il avec Spring Boot 1.4.3 et échoue-t-il avec Spring Boot 2 ? Est-il possible de configurer le bean pour qu'il se comporte de la même manière que l'ancienne version ?

0 votes

Avez-vous essayé de mettre à jour Jackson avec la dernière version stable 2.9.4 ? Le journal des modifications contient quelques corrections spécifiques liées à la désérialisation des cartes. github.com/FasterXML/jackson/wiki/Jackson-Release-2.9.3

0 votes

@LuisAguilar J'ai essayé une version plus récente mais rien n'a changé. J'ai différents DTO avec quelques chaînes de caractères qui n'ont pas non plus réussi à se désérialiser. Je pense que c'est lié d'une manière ou d'une autre à la configuration du mappeur d'objets de Spring, mais je n'ai rien trouvé concernant les constructeurs par défaut.

0 votes

Quelle version de Lombok utilisez-vous dans chaque cas ?

1voto

robjwilkins Points 2251

Comme d'autres l'ont dit, vous devez ajouter plus d'éléments à la liste. @Value pour indiquer à Lombok d'écrire le fichier @JsonCreator sur le constructeur généré

@AllArgsConstructor(onConstructor_={@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)})

Note une syntaxe légèrement différente des autres réponses ici si vous utilisez JDK8+ (ceci est mentionné dans la javadoc)

Si vous utilisez le plugin gradle freefair, vous devez également le configurer pour ajouter les propriétés du constructeur dans le fichier build.gradle :

lombok {
    config['lombok.anyConstructor.addConstructorProperties'] = 'true'
}

0voto

Chirag goyal Points 11

Si vous exécutez en mode natif et que l'erreur est due à la réflexion pour résoudre l'annotation de votre classe avec @RegisterForReflection et reconstruisez l'application et exécutez-la. Votre erreur sera résolue.

pour la recherche d'informations sur le enlace

0voto

fascynacja Points 345

J'ai mis à jour la version de lombok à : 'org.projectlombok:lombok:1.18.0' et cela a fonctionné pour moi.

0 votes

Hm, je ne vois rien qui soit en rapport avec les changeants.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X