Home » Java » java – JsonDeserialize set inherited properties also when objectmapper readvalue-Exceptionshub

java – JsonDeserialize set inherited properties also when objectmapper readvalue-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

JsonDeserialize not working when objectmapper readvalue for inherited properties.

Vehicle Class

@Getter
@Setter
@JsonDeserialize(builder = Vehicle.VehicleBuilder.class)
@Builder(builderClassName = "VehicleBuilder", toBuilder = true)
public class Vehicle{
    private String name;
    private String noOfTyres;
    @JsonPOJOBuilder(withPrefix = "")
    public static class VehicleBuilder{
    }
}

Car class

@Getter
@Setter
@JsonDeserialize(builder = Car.CarBuilder.class)
@Builder(builderClassName = "CarBuilder", toBuilder = true)
public class Car extends Vehicle {
    private String carType;

    @JsonPOJOBuilder(withPrefix = "")
    public static class CarBuilder extends VehicleBuilder {
    }
}

I don’t want to create @NoArgsConstructor ,@AllArgsConstructor in both classes.
My issue when Car car = om.readValue(jsonValue,Car.class);
When I parse Json to java object the parent class properties are not setting properly.

As of now I’m using @NoArgsConstructor ,@AllArgsConstructor for work around for the use case.

Is there any way to use it along with @JsonDeserialize and @JsonPOJOBuilder?

How to&Answers:

The problem with the code is that it assumes that builders in inherited classes will set the parent properties as well. Unfortunately, they don’t do that out of the box. However, this is something that can be achieved with Lombok but requires some additional code, as described in this post.

A complete solution could look as follows.

Parent Class

@Getter
@Setter
@JsonDeserialize
@Builder(builderClassName = "VehicleBuilder", builderMethodName = "vehicleBuilder")
public class Vehicle {
    private String name;
    private String noOfTyres;

}

Child Class

@Getter
@Setter
@JsonDeserialize(builder = Car.CarBuilder.class)
public class Car extends Vehicle {

    private String carType;

    @Builder
    public Car(String name, String noOfTyres, String carType) {
        super(name, noOfTyres);
        this.carType = carType;
    }

    @JsonPOJOBuilder(withPrefix = "")
    public static class CarBuilder extends VehicleBuilder {
    }

}

Notice that the builder on the extending class is achieved by supplying a constructor with the @Builder annotation. Also take notice that the extending class does not set annotation parameter toBuilder=true as that will require access to parent properties which are private. This can be achieved by setting parent class properties to protected.