logi0517
logi0517

Reputation: 845

PUT request with JSON payload sent from Postman, nested object not parsed

I didn't have this problem before, with other POJOs, I'm not sure what's different this time, but I can't get this working and I could not find an exact solution for this.

I have this POJO called Component (with some Hibernate annotations):

@Entity
@Table(name="component", uniqueConstraints={@UniqueConstraint(
    columnNames = {"name", "component_type"})})
public class Component {

@Column(name="id")
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;

@Column(name="name")
private String name;

@Column(name="component_type")
private String componentType;

@Column(name="serial_number")
private int serialNumber;

@Column(name="active_since")
private String activeSince;

@Embedded
private ComponentWearoutModel wearout;

public Component() {
}

public Component(String name, String componentType, int serialNumber, String activeSince,
        ComponentWearoutModel wearout) {
    this.name = name;
    this.componentType = componentType;
    this.serialNumber = serialNumber;
    this.activeSince = activeSince;
    this.wearout = wearout;
}

public ComponentWearoutModel getModel() {
    return wearout;
}

public void setModel(ComponentWearoutModel wearout) {
    this.wearout = wearout;
}

//more getters and setters

}

ComponentWearoutModel:

@Embeddable
public class ComponentWearoutModel {

private String componentType; //dont mind the stupid duplicate attribute
private Integer componentLifeExpectancy;
private Float componentWearOutLevel;
private Float actionThreshold;

public ComponentWearoutModel() {
}

public ComponentWearoutModel(String componentType, int componentLifeExpectancy, float componentWearOutLevel,
        float actionThreshold) {
    this.componentType = componentType;
    this.componentLifeExpectancy = componentLifeExpectancy;
    this.componentWearOutLevel = componentWearOutLevel;
    this.actionThreshold = actionThreshold;
}

//getters and setters
}

The sample payload I use:

{
"name": "component name",
"componentType": "airfilter2",
"serialNumber": 573224,
"activeSince": "2016-04-10 17:38:41",
"wearout":
    {
        "componentType": "airfilter",
        "componentLifeExpectancy": 1000,
        "componentWearOutLevel": 0.24,
        "actionThreshold": 0.2
    }
 }

And finally the resource class:

@Path("myresource")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON  + ";charset=UTF-8")
public class MyResource {

DatabaseManager dm = DatabaseManager.getInstance();

@PUT
@Path("Component")
public Response storeComponent(Component component){
    System.out.println("reached");
    System.out.println(component.getComponentType()); //okay
    System.out.println(component.getModel().getComponentType()); //nullpointerexception
    ComponentWearoutModel model = new ComponentWearoutModel("type", 1000,    1f, 0.2f);
    component.setModel(model); //this way it's saved in the db just fine
    dm.save(component);
    return Response.status(Status.OK).entity(component).build();
}
}

Without the prints, only the fields which are not part of the ComponentWearoutModel class are stored in the database table, the other columns are null. So when I try to print one of them, I get an exception, I just dont understand why. If I create a ComponentWearoutModel in the resource method and add it to the component, everything is fine in the database.

UPDATE:

so my mistake was that I named the ComponentWearoutModel attribute as "wearout" in the Component.class, but the autogenerated getters and setter were called getModel/setModel and moxy could not parse my payload because of this. Solution: change the attribute name to "model" in Component class and in payload too.

Upvotes: 0

Views: 905

Answers (1)

Sampada
Sampada

Reputation: 2991

Please ensure that the attribute names you are using in the POJO are same as what are being sent in the json string.

Since there are no jackson etc annotations being used in your POJO to tell it the corresponding json mapping, the underlying code will directly use the names given in json string. If you are using the string "model", the convertor code will look for a "setModel" method in your POJO.

In the above example, either call everything "model", or "wearable".

Upvotes: 1

Related Questions