No string-argument constructor/factory method to deserialize from string value

no string-argument constructor/factory method to deserialize from string value

Java is a popular and general-purpose programming language that works on different systems like Mac, Windows, Linux, etc. It is used for different purposes, all for programming. When working with Java, you may encounter no string-argument constructor/factory method to deserialize from string value warning.

Today we are going to discuss this Java error. Let’s see how this occurs and  how to fix this Java error

How To Fix no string-argument constructor/factory method to deserialize from string value

To fix the error, first we need to know how you may land up in this error when you code, then we shed light on all the possible solutions. Let’s take a look at how the error occurs

Issue

The error occurs when you are trying to use the ‘ObjectMapper’ class from the package ‘com.fasterxml.jackson.databind.  It happens when there is a parsing issue. You will get an error:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.graybar.utilities.ups.beans.Location: no String-argument constructor…

It occurs when using the web application in Angular JS, spring MVC. Take a look at the bean to see the causes of error in detail

@JsonIgnoreProperties(ignoreUnknown = true)
public class Lading {
    @JsonProperty("Work")
    private ArrayList<Work> work;
    public ArrayList<Work> getWork() {
        return work;
    }
    public void setWork(ArrayList<Work> work) {
        this.work = work;
    }
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Work {
    @JsonProperty("WorkLocation")
    private ArrayList<WorkLocation> workLocation;
    public ArrayList<WorkLocation> getWorkLocation() {
        return workLocation;
    }
    public void setWorkLocation(ArrayList<WorkLocation> workLocation) {
        this.workLocation = workLocation;
    }
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class WorkLocation {
    @JsonProperty("Location")
    private Location location;
    // GETTER
    public Location getLocation() {
        return location;
    }
    // SETTER
    public void setLocation(Location location) {
        this.location = location;
    }
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Location {
    @JsonProperty("Town")
    private String town;
    @JsonProperty("StateProvCode")
    private String stateProvCode;
    @JsonProperty("NationCode")
    private String nationCode;
    public String getTown() {
        return town;
    }
    public void setTown(String town) {
        this.town = town;
    }
    public String getNationCode() {
        return nationCode;
    }
    public void setNationCode(String nationCode) {
        this.nationCode = nationCode;
    }
    public String getStateProvCode() {
        return stateProvCode;
    }
    public void setStateProvCode(String stateProvCode) {
        this.stateProvCode = stateProvCode;
    }
}

Now, check out the code where json is properly mapped

public static void main(String[] args) {
     String jsonMessage = "" +
         "{" + 
         "   \"Work\": [{ " +
         "       \"WorkLocation\": { " +
         "           \"Location\": { " +
         "               \"Town\": \"Hana\", " +
         "               \"StateProvCode\": \"Hi\", " +
         "               \"NationCode\": \"US\" " +
         "           } " +
         "       } " +
         "   }, " +
         "   { " +
         "       \"WorkLocation\": { " +
         "           \"Location\": { " +
         "               \"Town\": \"Honolulu\", " +
         "               \"StateProvCode\": \"Hi\", " +
         "               \"NationCode\": \"US\" " +
         "           } " +
         "       } " +
         "   }] " +
     "} ";
     try {
         ObjectMapper mapper = new ObjectMapper();
         mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
         Lading lading = mapper.readValue(jsonMessage, Lading.class);
         System.out.println("lading.toString = " + lading.toString());
     } catch (Exception e) {
         e.printStackTrace();
     }
 }

Here, the error message warning shows up all the time you are trying to adjust the data in the‘jsonMessage’ var

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.graybar.utilities.ups.beans.Location: no String-argument constructor…

The problem occurs when:

"{" + 
     "   \"Work\": [{ " +
     "       \"WorkLocation\": { " +
     "           \"Location\": { " +
     "               \"Town\": \"Hana\", " +
     "               \"StateProvCode\": \"Hi\", " +
     "               \"NationCode\": \"US\" " +
     "           } " +
     "       } " +
     "   }, " +
     "   { " +
     "       \"WorkLocation\": { " +
     "           \"Location\": \"\" " +
     "           } " +
     "       } " +
     "   }] " +
     "} ";

When trying to change the json from the following

{
     "WorkLocation": { 
         "Location": {
             "Town": "Honolulu", 
             "StateProvCode": "Hi", 
             "NationCode": "US"
         }
     }
 }]

Into the code below

{
 "WorkLocation": {
      "Location": ""
     }
 }

Solution To Fix the no string-argument constructor/factory method to deserialize from string value

Solution 1

When you are coding, try to set the below code in your program can solve the issue

mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

or you can also add

mapper.configure(
           DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,
           true)

You can set this according to the version you are using.

Solution 2

You need to check how you are calling the method as arguments can be the same and that’s when yourIDE can catch many things.

You need to use: mapper.readValue(...)

If you have used the following, then you need to replace

mapper.convertValue(...)

Solution 3

In most of cases, the below code works wonders

ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"symbol\":\"ABCD\}";
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
Trade trade = objectMapper.readValue(jsonString, new TypeReference<Symbol>() {});

When using the code, you can get the error solved. Check out

@JsonIgnoreProperties    public class Symbol {
    @JsonProperty("symbol")
    private String symbol;
}

Solution 4

Another basic solution to this issue is to replace “” with curly brackets {} as the deserializer doesn’t identify the location constructor with a string argument.

Conclusion

Here we have discussed how you get the error no string-argument constructor/factory method to deserialize from string value along with the issue sample code. We also highlighted the possible solutions to get through the issue. Hope you find it helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *