0

I am writing an Android app that needs to download data from a server and persist the data in an SQLite database on the android client. I have broken this problem down into two steps:

1) fetch data from server and populate a model on the android client. 2) persist data from the model in an SQLite DB on the android client.

I have successfully implemented step 1, but am having trouble with step 2.

I decided to use ActiveAndroid to help with step 2. I am confused about how to do this though. My main sticking point is whether or not I am supposed to use ActiveAndroid's @Column() and @Table() annotations in my current model. This model is currently populated after a server call (using the ION library for the networking) so do I just add these annotations directly to that model? I have tried this and am getting a StackOverflowError.

Here's the model I'm using:

@Table(name = "Issue")
public class Issue extends Model {

private static final long serialVersionUID = 0L;

@Column(name = "uid")
@SerializedName("id")
public int id;
@Column(name = "name")
public String name;
@Column(name = "created_at")
public String created_at;
@Column(name = "updated_at")
public String updated_at;
@Column(name = "description")
public String description;
@Column(name = "conference_number")
public String conference_number;
@Column(name = "hash_key")
public String hash_key;
@Column(name = "owner_id")
public int owner_id;
@Column(name = "categories_updated_at")
public String categories_updated_at;
@Column(name = "deleted_at")
public String deleted_at;
@Column(name = "status")
public String status;
@Column(name = "external_reference_id")
public String external_reference_id;
@Column(name = "messages_updated_at")
public String messages_updated_at;
@Column(name = "unknowns_updated_at")
public String unknowns_updated_at;
@Column(name = "facts_updated_at")
public String facts_updated_at;
@Column(name = "action_items_updated_at")
public String action_items_updated_at;
@Column(name = "uploads_updated_at")
public String uploads_updated_at;
@Column(name = "involvements_updated_at")
public String involvements_updated_at;
}

If, in the code above, I remove all of the annotations, and remove the "extends Model" I am left with code that solves my problem in Step #1. However, using the code above I get a StackOverFlow error and here is the stacktrace:

java.lang.StackOverflowError
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
            at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:355)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:117)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
            at com.google.gson.Gson.getAdapter(Gson.java:356)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
            at com.google.gson.Gson.getAdapter(Gson.java:356)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
            at com.google.gson.Gson.getAdapter(Gson.java:356)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
            at com.google.gson.Gson.getAdapter(Gson.java:356)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
            at com.google.gson.Gson.getAdapter(Gson.java:356)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
            at com.google.gson.internal.bind.ReflectiveTypeAdapter

The stacktrace leads me to believe that my networking library (ION) is having trouble mapping the JSON (using GSON) to my java object (model). However the only way I can think to solve this is to use a one object for storing the data returned from the network, and another, similar object that maps to the DB but that seems hacky. Can anyone point me in the right direction?

neonDion
  • 2,278
  • 2
  • 20
  • 39

1 Answers1

1

I know it's late but the problem is gson tries to serialize a Class<?> at com/activeandroid/TableInfo.java.

You could just set the mType field to transient at com/activeandroid/TableInfo.java since you don't need this field to be serialized anyway:

private transient Class<? extends Model> mType;

Or you could work with @Expose annotation and do something like:

new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

Or even checkout Gson Exclusion Strategy

vinitius
  • 3,212
  • 2
  • 17
  • 22