0

I have the following Java beans:

public class Customer implements Serializable {

    private Integer id;

    private String name;

    private Country country;

    public void setId(Integer id) {
        this.id=id;
    }

    public void setName(String n) {
        this.name=n;
    }

    public void setCountry(Country c) {
        this.country=c;
    }

    public void setCountryId(Integer id) {
        this.country= new Country();
        this.country.setId(id)
    }

    //...getters here
}

and

public class Country {
    private Integer id;
    private String code; //es, us, fr...

    private void setId(Integer id) {
        this.id=id;
    }

    //rest of setters and getters
}

and I have the following method:

@RequestMapping(value = "/customer/", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<Customer> addSecondaryCustomer(@RequestBody Customer sc) {
    this.customerService.addCustomer(sc);

    return new ResponseEntity<>(sc,HttpStatus.OK);

}

Using the Web Development tools I can see the server is receiving the following:

{ 
  "name": "Pablo Test",
  "countryId": 1
}

I can see that the field name is populated, but country remains null. I've tried to set a breakpoint in both setters, but none of them is being called, so it seems that the object mapper is looking for attributes, ignoring setters. ¿Why is this happening?

I am using Jackson 2.9.0 and Spring 4.2.13. It worked with older versions of Spring (4.2.0) and Jackson (2.1.4)

PS: I know I can workaround this by sending "country": { "id": 1} in my AJAX request, but I need to know what's happening here.

Pablo Lozano
  • 10,122
  • 2
  • 38
  • 59
  • Not necessarily that. Jackson has several configuration options related to how to convert JSON keys to java property names. – M. Prokhorov Jan 31 '18 at 15:01
  • I haven't defined a custom ObjectMapper, this is happening with out-of-the-box configuration – Pablo Lozano Jan 31 '18 at 15:10
  • Why Country is not Serializable ? – JPRLCol Jan 31 '18 at 16:47
  • @JPRLCol The Country instance is created by the setter, Jackson is not aware of it. But as I wrote, if I change my JSON from `"countryId": 1` to `"country": { "id": 1}` it works, so not being Serializable is not an issue (I think, I will test it anyway) – Pablo Lozano Jan 31 '18 at 17:16
  • @PabloLozano it would be necessary to see what is the actual data you are trying to return – JPRLCol Jan 31 '18 at 17:18
  • 1
    @PabloLozano, I did a bit of digging in Jackson sources, and there is a pivot where it decides what to use: field assignment or setter method. For some reason, Jackson doesn't find your setter method acceptable, which I suppose you can solve by annotating as `@JsonSetter`. However, looking at sources I wasn't able to tell _why_ it does that with fully default configuration (it all looks as if should use your setter), so maybe you'll want to debug that yourself: write a test and call it with brand new `ObjectMapper`, then look what it does and why. – M. Prokhorov Feb 01 '18 at 14:18

0 Answers0