retrofit and orm library throw StackOverflow

江枫思渺然 提交于 2019-12-31 04:18:07

问题


I try to use 2 libraries:

  • square/Retrofit - Rest client
  • satyan/sugar - db orm

retrofit use gson, so do class

public class Book{
    String name;

    public Book(String name) {
        this.name = name;
    }
}

ok, retrofit succesfully get data from server and put in our Book class.

now i want save this data. for use orm need extend parent class

    public class Book extends SugarRecord<Book>{
    String name;

    public Book(String name) {
        this.name = name;
    }
}

but after extend the parent class, retrofit cannot parse json.

so we get an error:

java.lang.RuntimeException: An error occured while executing doInBackground()
...
Caused by: retrofit.RetrofitError: java.lang.StackOverflowError at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:390)
...
Caused by: java.lang.StackOverflowError at  com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
...

how to make friends 2 libraries that they use one object class?

or how to specify the retrofit, so that it did not touch Book's class parent?


回答1:


Error happens when Gson tries to resolve type information about an object it have to deserialize. It gets into an infinite recursion due to the cyclic reference to your Book class in extends declaration.

However even if Gson could cope with your class, I would not recommend using these libs combination.

You see, what Gson does is much alike to what standard Java serialization does but in JSON format. I mean that Gson takes the internal state of your object and performs its serialization. And when it parses JSON it creates an object with the state specified in this JSON.

If you take a look at SugarRecord class, you'll see that it has a field named "tableName". Thus if you passed your Book object to Gson instance, you'd get

{name: "book name", tableName: "table_book"}.

Moreover, if you got a response from server which is like

{name: "another book name", tableName: "something absolutely unrelated"},

you would get an instance of Book with a state exactly matching what is described in this response. Meaning, with tableName being not equal to what you would like...

You could workaround this issue using exclusion strategies in Gson, but overall you'll get yet another problem.

P.S. After a quick look at SugarRecord class on github I do not understand why it has a type parameter at all. It's even not used really. Thus technically I think you'll be able to combine these 2 libraries, if you skip type parameter in extends declaration making your class look like class Book extends SugarRecod { }, and use an exclusion strategy. Yet, I wouldn't do it myself in practice :).




回答2:


Your POJO class need a empty constructor :

you shoud add this constructor to your Book class:

public Book(){

}


来源:https://stackoverflow.com/questions/24014735/retrofit-and-orm-library-throw-stackoverflow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!