objectbox-java
objectbox-java copied to clipboard
Improve relations to play nicer with server APIs (e.g. Retrofit, GSON, Jackson, Moshi, ...)
If you get object data from another source (e.g. server) you can make those data objects also ObjectBox entities. One thing has to be considered: relations on ObjectBox currently rely on ToOne
and ToMany
types, which 3rd party libraries are not aware of.
A quick work around would probably be to walk through the object graph and replace List
objects with ToMany
objects.
However, we could also look into supporting plain java.util.List
s in some way. A put
would have to detect the type and do some additional syncing to figure out what to do. Or maybe just plainly put
all objects in the list?
That would fix #95 for me.
Not 100% certain how to implement it. Somewhat hesitant to enable putting entire lists as this may "encourage" it, which just might be wrong in other scenarios. Maybe having a new marker annotation to enable it?
An annotation for automatic inserting lists would be great.
Is there any news on this? Currently running into this exact same issue (of toOne's not being recognised by a 3rd party), and would love to keep on using ObjectBox without having to build costly wrappers around everything...
Seconded. Meanwhile, out of curiosity, what is the fix you guys are using?
Something like order.forEach { order -> order.customer.target = order }
?
Yep, with .setTarget(order). Seems like the right way around this for the moment.
Yes please. Would like to use an ObjectBox "entity" as a model of Retrofit responses too. Using Moshi for the json adapter. Please suggest a way to use these together.
Any ETA on this? Looking to move from Realm to ObjectBox but this issue is making it difficult.
I concur in regards to having an annotation based solution @ToOne
@ToMany
POJOS or in this case entities should not be closely tied to a database.
Having something like:
@Many List<Stuff> stuff
Would solve many of the issues here
I have a class with ToMany object, and using retrofit as rest client. I am getting this error while loading data,
FATAL ERROR field com.company.entity.Receipt.receipt_items has type io.objectbox.relation.ToMany, got java.util.ArrayList
This is my class structure.
@Entity
public class Receipt implements Serializable {
public ToMany<ReceiptItem> receipt_items;
@Id
public long id;
public long receipt_no;
}
Issue is arraylist not mapping to ToMany object.
@indrakumarprajapat Is this a JSON parsing error? For example with GSON you might have to create a type adapter for ToMany
. -ut
okay, I got it, but can you help me, how can I do that. i have little bit idea. but not sure how to do it exacly.
@indrakumarprajapat Sorry, not here. Please look in the GSON documentation or ask for example on Stack Overflow for help. -ut
Sorry for late reply, the issue is fixed by type adapter. thanks.
I don't like this solution but it works. you have to implement JsonDeserializer.
public class MyDeserializer<T extends FromJson> implements JsonDeserializer<T> {
@Override
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
T var = ((Class<T>) typeOfT).newInstance();
var.fromJson(json.getAsJsonObject());
return var;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
}
create Gson object to use with Retrofit
Gson gson= new GsonBuilder()
.registerTypeHierarchyAdapter(FromJson.class, new MyDeserializer())
.create();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
FromJson interface and some example.
public interface FromJson {
void fromJson(JsonObject jo) throws JSONException;
}
@Entity
public class Status implements FromJson {
public long id;
public int code;
public String message;
public void fromJson(JsonObject jo) throws JSONException {
this.code = jo.get("code").getAsInt();
this.message = jo.get("message").getAsString();
}
}
@Entity
public class Login implements FromJson {
public long id;
public ToOne<User> user;
public ToOne<Status> status;
@Override
public void fromJson(JsonObject jo) throws JSONException {
Status s = new Status();
s.fromJson(jo.get("status").getAsJsonObject());
this.status.setTarget(s);
User u = new User();
u.fromJson(jo.get("user").getAsJsonObject());
this.user.setTarget(u);
}
}
Any example using TypeAdapter? example provided by @greenrobot-team is dead.
@indrakumarprajapat How does the TypeAdapter work? Could U show me a simple demo ? Thks :)
I'm not sure any of the comments here directly reflect the case of simple nested objects, of the type that crop up all the time in JSON data feeds, e.g.:
{
"name": "Acme Inc.",
"location": {
"longitude": 1.23456,
"latitude": 6.54321
}
}
Which might deserialize to...
public class Location
{
private double longitude;
private double latitude;
// getters, setters etc.
}
@Entity
public class Business
{
private String name;
// HOW TO PERSIST THIS??
private Location location;
}
These are a problem too, but we don't usually need an entity relationship here. Something more like Room's @Embedded
annotation would be sufficient.
(I think this is more accurately covered by https://github.com/objectbox/objectbox-java/issues/217 which is marked as a duplicate of this issue.)
I gave up because of this problem, and I don't think this data structure design is reasonable enough.
@lgengsy Could you provide a little bit info for us, so we can fix it?
@indrakumarprajapat How does the TypeAdapter work? Could U show me a simple demo ? Thks :)
Quick poll: Do you mostly need this for List
? Or is ToOne
a hard requirement?
At first, I thought this project could help me deal with data caching problems quickly. I tried it. When I met toMany and toOne, I found the project was getting more and more complicated. It took me a day or two to adjust my data structure. Finally, I found it too hard to change back.
Any new solutions or workarounds? Or better look for another ORM? (Room?) Creating an adapter for each entity not really an option
Any solutions for ToOne or ToMany to work with Retrofit?
Is there any solution for deserialize ToOne Object Using Gson Converter ? @greenrobot @greenrobot-team
Is there any update or any solution for working with Gson?
@greenrobot @greenrobot-team Can you summarize the specific implementation? It is best to add to the document
I have the same issue. Please, implement annotation for ToOne.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of io.objectbox.relation.ToOne (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
java.lang.IllegalArgumentException: field .bean.SubscribeBean.cates has type io.objectbox.relation.ToMany, got java.util.ArrayList
@Backlink(to = "subscribeBean") private ToMany<NewsBean> cates;
I still can't find the exactly method to resolve this problem,could you give some example?retro+objectbox