0

I'm using Spring Boot with the expected dependencies (Jackson, Hibernate etc.).

I'm have a table called Buildings where Unit, Number, Street etc. are all columns. But I prefer to parse this and return this as a class I created called "StreetAddress".

When I send this JSON, I get an error.

"address": {
    "unit":"0101",
    "number":"19",
    "suffix":"STREET",
    "suburb":"Example",
    "state":"EXP",
    "streetName":"Example",
    "postCode":"400"
}

This is the error:

Cannot construct instance of `com.App.Entity.Helpers.StreetAddress` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

I have this as setAddress in my Building model. Is there any annotation I can use to tell Jackson how to parse this properly?

private String subunit;
private Integer number;
private String streetname;
private String suffix;
private String suburb;
private String state;
private Integer postcode;    

public void setAddress(StreetAddress address) {
        this.subunit = address.getUnit();
        this.number = address.getNumber();
        this.streetname = address.getStreetName();
        this.suffix = address.getSuffix().toString();
        this.suburb = address.getSuburb();
        this.state = address.getState().toString();
        this.postcode = address.getPostCode();
    }

Clarification:

public class StreetAddress {
private String unit;
private Integer number;
private String streetname;
private StreetSuffix suffix;
private String suburb;
private AUState state;
private Integer postcode;

public StreetAddress(String unit, int number, String street, StreetSuffix suffix, String suburb, AUState state, int postcode) {
    this.unit = unit;
    this.number = number;
    this.streetname = street;
    this.suffix = suffix;
    this.suburb = suburb;
    this.state = state;
    this.postcode = postcode;
}

public String getUnit() {
    return unit;
}

public Integer getNumber() {
    return number;
}

public String getStreetName() {
    return streetname;
}

public String getSuffix() {
    return suffix.toString();
}

public String getSuburb() {
    return suburb;
}

public AUState getState() {
    return state;
}

public Integer getPostCode() {
    return postcode;
}

}

Sarah Macey
  • 196
  • 1
  • 12
  • How is `StreetAddress` defined? – meriton Jul 24 '19 at 12:01
  • It's not, otherwise I believe Spring will look for a StreetAddress object in a related table. – Sarah Macey Jul 24 '19 at 12:03
  • By "defined", I mean the class declaration you wrote. You said that you have created the class, after all? Most likely there is something missing there. – meriton Jul 24 '19 at 12:08
  • `public class StreetAddress { private String unit; private Integer number; private String streetname; private StreetSuffix suffix; private String suburb; private AUState state; private Integer postcode; public StreetAddress(String unit, int number, String street, StreetSuffix suffix, String suburb, AUState state, int postcode) { this.unit = unit; this.number = number; this.streetname = street; this.suffix = suffix; this.suburb = suburb; this.state = state; this.postcode = postcode; }` – Sarah Macey Jul 24 '19 at 12:14
  • ^ With only getters, no setters. Could that be the problem? – Sarah Macey Jul 24 '19 at 12:15
  • For future reference: You can use the edit link below your question to edit clarifying info into the question itself. That way the infos is not squeezed into a tiny comment box, making it easier to read. – meriton Jul 24 '19 at 12:19
  • Apologies, added :) – Sarah Macey Jul 24 '19 at 12:21
  • 1
    how about this? https://stackoverflow.com/questions/4982340/jackson-builder-pattern – Magd Kudama Jul 24 '19 at 12:23
  • I've added the setters and the annotations recommended however still getting the same error. – Sarah Macey Jul 24 '19 at 12:41

1 Answers1

1

The error message says that Jackson doesn't know how to create an object of type StreetAddress, because it could not find a suitable constructor. Jackson either expects a parameterless constructor (in which case it will pass the JSON data by assigning fields or calling setters), or a constructor with annotations that tell Jackson which JSON attribute should be passed to which parameter.

The easiest way to resolve this is to simply not declare a constructor, and make the fields public instead:

public class StreetAddress {
    public String unit;
    // ... more fields here
}

Alternatively, you can keep the fields private, but declare a setter for each field:

public class StreetAddress {
    private String unit;
    // ... more fields here

    public void setUnit(String unit) {
        this.unit = unit;
    }
    // ... more setters here
}
meriton
  • 68,356
  • 14
  • 108
  • 175
  • Doesn't seem to work for me. I added setters, but I left the constructor in there (as I use it) - do I need to remove the constructor? – Sarah Macey Jul 24 '19 at 12:42
  • As I said: You must either provide a parameterless constructor, or annotate your existing constructor so Jackson knows which JSON attribute goes into which parameter. So you can either provide an additional parameterless constructor to make it use the setters (or public fields), or [annotate your constructor so Jackson knows which JSON-attribute goes into which parameter](https://stackoverflow.com/a/25085675/183406). – meriton Jul 24 '19 at 12:52
  • Ah I understand - you're correct and this has fixed it. Thank you very much! – Sarah Macey Jul 24 '19 at 12:58