Objectbox-java: Gson doesn't parse from 'JSON to entity' which contains a ToOne relation object.

Created on 18 Oct 2017  路  13Comments  路  Source: objectbox/objectbox-java

My Entity is as follows.

@Entity
public class Conference {

@Id(assignable = true)
public long conferenceID;
public ToOne<ConferenceAgenda> agenda;

}

I am getting a JSON response from server as

{"conferenceID":2,"agenda":{"days":[{"title":"day-1"}]}}

I am trying to parse the above JSON to the entity. "conferenceID" is getting parsed but the "agenda"
doesn't get parsed. Am I doing something wrong or is there any other way I can parse the JSON.

objectboxVersion : 1.1.0

Most helpful comment

Is here already a (easy) solution known?

All 13 comments

@sandeep466github Please refer to #104 for better understanding.

@sandeep466github Is there a way to tell GSON to use a setter instead of using the field directly? Then you could have a setAgenda(ConferenceAgenda confAgenda) setter calling agenda.setTarget(confAgenda).

@greenrobot What i have observed and encountered while parsing json response through GSON is when we provide a ToOne or ToMany types to the GSON then it always throw StackOverFlow error.

@errohitgupta Can you share the relevant part of the stack in a new issue if you think this is a bug? Thank you!

@greenrobot we are using Gson with direct access of members instead of setters and getters. Can you elaborate some more on what you said.

OH GSON seems to still force you to use fields: https://github.com/google/gson/issues/232

I was never a big Gson fan (favoring Moshi and Jackson personally) and haven't done much with it. Maybe there are configurations to allow this, but I don't know.

Another possibility could be to provide some custom serializer/deserializer for ToOne, see https://github.com/google/gson/blob/master/UserGuide.md#TOC-Custom-Serialization-and-Deserialization

@greenrobot So do you recommend JACKSON instead of GSON to go hand to hand with Objectbox. If yes then I will switch to JACKSON. I will also take a look into serializer/deserializer.

Maybe a possible workaround: add a field annotated with @Transient (the ObjectBox version, which should be ignored by Gson) that Gson can deserialize into. Then post-process your objects and manually call agenda.setTarget(parsedAgenda).

Edit: but I suppose only writing a custom de/serializer for each entity works properly. That's a lot of work though. But it can properly set the ToOne/ToMany values:

entity.order.setTarget(order);
entity.orders.addAll(orders);

-ut

@greenrobot-team so how to Initialization the agenda in kotlin :lateinit var agenda: ToOne<>

Is here already a (easy) solution known?

Had to work with Gson recently. You probably have to write a custom deserializer for each entity. An example:

@Entity class User {
    private ToOne<Status> status;
    private ToMany<Address> addresses;
    // TODO getters/setters
}

class UserDeserializer implements JsonDeserializer<User> {
    @Override
    public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        JsonObject userJson = json.getAsJsonObject();
        User user = new User(); // ToOne and ToMany initialized here through code injected by ObjectBox plugin

        // ToOne
        JsonObject statusJson = userJson.getAsJsonObject("status");
        Status status = context.deserialize(statusJson, Status.class);
        user.getStatus().setTarget(status);

        // ToMany
        JsonArray addressesJson = userJson.getAsJsonArray("addresses");
        Type addressListType = new TypeToken<ArrayList<Address>>(){}.getType();
        ArrayList<Address> addresses = context.deserialize(addressesJson, addressListType);
        user.getAddresses().addAll(addresses);

        // TODO parse other properties

        return user;
    }
}

Also posted this in https://github.com/objectbox/objectbox-java/issues/104#issuecomment-496384138.

-Uwe

Closing this in favor of #104. Please thumbs up that one.

Was this page helpful?
0 / 5 - 0 ratings