Reputation: 105
I'm using Lombok, and the @Annotations create getters, setters, and constructors for me. I have many other classes which Jackson deserializes easily. Here is the object I'm trying to deserialize to:
@Value
@Builder
public class RecipeListRemoveDTO {
int recipeListId;
}
Used within the following Controller method:
@DeleteMapping(path="/deleteRecipeListFromUser")
public @ResponseBody String deleteRecipeListFromUser(@RequestBody RecipeListRemoveDTO recipeListRemoveDTO) {
return recipeListService.removeRecipeListFromUser(recipeListRemoveDTO);
}
And the JSON I am sending:
{
"recipeListId": 2
}
But I'm receiving the error:
"message": "JSON parse error: Cannot construct instance of com.prepchef.backend.models.dto.RecipeListRemoveDTO (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.prepchef.backend.models.dto.RecipeListRemoveDTO (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (PushbackInputStream); line: 2, column: 5]"
Does anyone know why this may be the case?
Upvotes: 5
Views: 1270
Reputation: 10127
Jackson didn't know that it should use the Lombok-generated builder.
Probably the easiest solution is to annotate your class also with Lombok's @Jacksonized
annotation (available since Lombok
1.18.14).
@Value
@Builder
@Jacksonized
public class RecipeListRemoveDTO {
int recipeListId;
}
Under the hood the @Jacksonized
annotation causes Lombok
to do the following things (so that you don't need to do these
manually):
@JsonDeserialize(builder=RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class)
to your class, so that Jackson knows it should use
the builder for deserialization.@JsonPOJOBuilder(withPrefix="")
to the builder class,
so that Jackson knows the buillder methods have a name
not beginning by with
.Upvotes: 3
Reputation: 18245
@Value
@Builder
@JsonDeserializer(builder = RecipeListRemoveDTO.RecipeListRemoveDTOBuilder.class)
public final class RecipeListRemoveDTO {
int recipeListId;
@JsonPOJOBuilder(withPrefix = "")
public static final class RecipeListRemoveDTOBuilder {}
}
Upvotes: 0
Reputation: 3980
The reason this doesn't work is that when you use @Value
in conjunction with @Builder
, no public
constructor is generated:
Also, any explicit constructor, no matter the arguments list, implies lombok will not generate a constructor. If you do want lombok to generate the all-args constructor, add @AllArgsConstructor to the class.
and
applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class
So, in summary, if you wish to maintain the immutability provided by @Value
, in this case you also need to add @AllArgsConstructor
.
Upvotes: 1