Mridang Agarwalla
Mridang Agarwalla

Reputation: 45108

How can I map a duplicately named field when deserializing using Jackson?

I have a simple Java class that looks like this:

public class AllAdverts {

    @JsonIgnoreProperties(value="id", ignoreUnknown=true)
    public static class Advert {

        @JsonProperty(value="_id")
        public String advertId;

        public String adgroupId;
    }

    public List<Advert> adverts;

    public AllAdverts(String json) throws IOException {
        this.adverts = MyUtils.mapper.readValue(json, 
                new TypeReference<List<Advert>>(){});
    }
}

I'm trying to deserialize the following bit of JSON:

[
    {
        "_id": "535788abf789b8916a8b456e",
        "adgroup_id": "535788abf789b8916a8b456c",
        "subcampaign_id": "535788abf789b8916a8b4569",
        "id": 6005879321807,
    },
    {
        "_id": "535788abf789b8916a8b456f",
        "adgroup_id": "535788abf789b8916a8b456c",
        "subcampaign_id": "535788abf789b8916a8b4569",
        "id": 6005879319007,
    }
]

When i pass in the JSON into the constructor of the class AllAdverts, the JSON gets mapped properly except the field called advertId.

As you can see, the JSON has two fields called id and _id, both of which I think Jackson treats as id and therefore, I am unable to load this. How can I resolve this issue? I've been digging through the docs and thought that the JsonProperty annotation would solve this, but it hasn't worked. While adgroupId has a value, advertId is null.

Upvotes: 0

Views: 184

Answers (2)

BBacon
BBacon

Reputation: 2678

Is you mapper consuming/removing underscores and replacing the uppercase letters to lowercase ones to fill the bean properties? Because that's what seems to be happening. Jackson would not fill the adgroupId field if not.

Check your mapper.

Here follows my code working with no problems at all (realize that I had to annotate the adgroupId field because of the name difference between the json and pojo field:

Main.java

import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {

    public static void main(String[] args) throws Exception {
        new Main().start();
    }

    public List<Advert> adverts;

    private void start() throws Exception {

        String jsonString =
                "[" +
                    "{" +
                        "\"_id\": \"535788abf789b8916a8b456e\"," +
                        "\"adgroup_id\": \"535788abf789b8916a8b456c\"," +
                        "\"subcampaign_id\": \"535788abf789b8916a8b4569\"," +
                        "\"id\": 6005879321807," +
                    "}," +
                    "{" +
                        "\"_id\": \"535788abf789b8916a8b456f\"," +
                        "\"adgroup_id\": \"535788abf789b8916a8b456c\"," +
                        "\"subcampaign_id\": \"535788abf789b8916a8b4569\"," +
                        "\"id\": 6005879319007," +
                    "}" +
                "]";

        ObjectMapper mapper = new ObjectMapper();

        JSONArray jsonArray = new JSONArray(jsonString);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);

            Advert advert = mapper.readValue(jsonObject.toString(), Advert.class);

            System.out.println("advertId: " + advert.advertId);
            System.out.println("adgroupId: " + advert.adgroupId);
        }

    }

}

Advert.java

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(value = "id", ignoreUnknown = true)
public class Advert {

    public Advert() {}

    @JsonProperty(value = "_id")
    public String advertId;

    @JsonProperty(value = "adgroup_id")
    public String adgroupId;

}

I'm using Jackson 2.4.1.

Upvotes: 1

Michał Ziober
Michał Ziober

Reputation: 38710

I think that you have to provide custom names for all properties using JsonProperty annotation. See example:

@JsonIgnoreProperties(value = "id", ignoreUnknown = true)
class Advert {

    @JsonProperty(value = "_id")
    public String advertId;

    @JsonProperty(value = "adgroup_id")
    public String adgroupId;

    // getters, setters

}

Upvotes: 0

Related Questions