JsonIgnoreProperties doesn't work with JsonCreator constructor

Arian Hosseinzadeh :

I have the following entity which I use as a target POJO for one of the requests to a controller:

Entity
@Table(name="user_account_entity")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(using = UserAccountSerializer.class)
public class UserAccountEntity implements UserDetails {
    //...
    private String username;

    private String password;

    @PrimaryKeyJoinColumn
    @OneToOne(mappedBy= "userAccount", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private UserEntity user;

    @PrimaryKeyJoinColumn
    @OneToOne(mappedBy= "userAccount", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private UserAccountActivationCodeEntity activationCode;

    @JsonCreator
    public UserAccountEntity(@JsonProperty(value="username", required=true) final String username, @JsonProperty(value="password", required=true) final String password) {
      //....
    }

    public UserAccountEntity() {}

    //.....
}

When I put unexpected fields in the request, it throws MismatchedInputException and fails with this message:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.myproject.project.core.entity.userAccountActivationCode.UserAccountActivationCodeEntity` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('9WL4J')
 at [Source: (PushbackInputStream); line: 4, column: 20] (through reference chain: com.myproject.project.core.entity.userAccount.UserAccountEntity["activationCode"])

In the controller I have:

@InitBinder
public void binder(WebDataBinder binder) {
    binder.addValidators(new CompoundValidator(new Validator[] {
            new UserAccountValidator(),
            new UserAccountActivationCodeDTOValidator() }));
}

And the endpoint that I make request to is:

@Override
public UserAccountEntity login(@Valid @RequestBody UserAccountEntity account,
        HttpServletResponse response) throws MyBadCredentialsException, InactiveAccountException {
    return userAccountService.authenticateUserAndSetResponsenHeader(
            account.getUsername(), account.getPassword(), response);
}

Update 1

The code for UserAccountSerializer:

public class UserAccountSerializer extends StdSerializer<UserAccountEntity> {

    public UserAccountSerializer() {
        this(null);
    }

    protected UserAccountSerializer(Class<UserAccountEntity> t) {
        super(t);
    }

    @Override
    public void serialize(UserAccountEntity value, JsonGenerator gen,
            SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        gen.writeStringField("id", value.getId());
        gen.writeStringField("username", value.getUsername());
        gen.writeEndObject();
    }

}
Camille Vienot :

The error is triggered because you have in your json :

"activationCode" : "9WL4J"

However Jackson does not know how to map the string "9WL4J" to the object UserAccountActivationCodeEntity

I guess the string "9WL4J" is the value of the primary key id of UserAccountActivationCodeEntity, in which case you should have in the json :

"activationCode" : {"id" : "9WL4J"}

If it is not the case use a custom Deseralizer to tell Jackson how to map the string to the object. You could use @JsonDeserialize on your entity.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=83871&siteId=1