Ravers
Ravers

Reputation: 1040

Android Sugar ORM - Class model with list

I am trying to integrate my android project with a SQLite database, but I'm pretty new to this database stuff so I use Sugar ORM to help me with the database side of the project.

The problem is one of my class model contains Lists:

public class MyObject extends SugarRecord implements Parcelable {

    public String myString;
    public List<String> myStringList;

    public MyObject () { }

    private MyObject (Parcel in) {
        myString= in.readString();
        myStringList= new ArrayList<>(); 
        in.readList(myStringList, String.class.getClassLoader());
    }

    public static final Creator<MyObject> CREATOR = new Creator<MyObject>() {
        public MyObjectcreateFromParcel(Parcel in) { return new MyObject(in); }
        public MyObject[] newArray(int size) { return new MyObject[size]; }
    };

    @Override
    public int describeContents() { return 0; }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(myString);
        dest.writeList(myStringList);
    }
}

When I try to read my database I get this error:

Class cannot be read from Sqlite3 database. Please check the type of field myStringList(java.util.List)

I suppose the way the columns are created on my database don't support lists. Is there any workaround for this? How should I aproach this?

Upvotes: 3

Views: 4060

Answers (5)

Bruno Andrade
Bruno Andrade

Reputation: 281

All options above work. But a way better approach is to override the toString method on the object being listed and return the json string:

public class Book extends SugarRecord {
    @Override
    public String toString() {
        return App.getGson().toJson(this);
    }
}

Pratical, fast, and works perfectly.

Upvotes: 1

Ibrahim.H
Ibrahim.H

Reputation: 1195

Similar to what @Seth Kigen does, but instead of overriding save() method, I'm using setter/getter to store myStringList as a String:

@CompileStatic
class MyObject  extends SugarRecord {

    @Ignore
    private List<String> myStringList

    // do not use this field
    String myStringListStore

    List<String> getMyStringList() {
        return myStringListStore.split(',').toList()
    }

    void setMyStringList(List<String> a) {
        this.myStringListStore = a.toString()
    }
}

This is Groovy code, but java code won't be very different, usage:

    MyObject b1 = new MyObject()
    b1.myStringList = ['Lars Vogella','Subramanian']
    if (b1.save()){
        Log.d('DEBUG', "'${b1}' Saved.")
    }

This should work for a simple usage (I've tested it with Groovy), for more complex List you might need to convert myStringList to JsonObject and update the setter/getter as you want. Hope this helps.

Upvotes: 0

Seth Kigen
Seth Kigen

Reputation: 101

SugarORM doesn't support storing Array or Lists There are strategies that you can use to support this but will require you to introduce a dependency.

The basic idea is to convert the list of data into JSON then store it as String

import com.google.gson.Gson;

public class MyObject extends SugarRecord implements Parcelable {
    public String myString;
    @Ignore //Sugar will ignore this field. 
    private List<String> myStringList;  //Change to private (accessed via getter/setter method)
    private String myStringListStore; //to store the list in JSON format. 

    public MyObject () { }

    private MyObject (Parcel in) {
        this.myString= in.readString();
        this.myStringList= new ArrayList<>(); 
        in.readList(myStringList, String.class.getClassLoader());
    }

    public static final Creator<MyObject> CREATOR = new Creator<MyObject>(){
        public MyObjectcreateFromParcel(Parcel in) { return new MyObject(in); }
        public MyObject[] newArray(int size) { return new MyObject[size]; }
    };

    public List<String> getMyStringList(){
        //Convert from JSON string to List
       myStringList =  new Gson().fromJson(this.myStringListStore,new TypeToken<List<String>>(){}.getType());
       return myStringList;
    }

    public setMyStringList(List<String> stringList){
        this.myStringList = stringList;
    }

    //Override save to ensure the list is converted into JSON before saving. 
    @Override
    public long save(){
        this.myStringListStore = new Gson().toJson(stringList); 
        return super.save();
    }

    @Override
    public int describeContents() { return 0; }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(myString);
        dest.writeList(getMyStringList());
    }
}

Upvotes: 3

lm2a
lm2a

Reputation: 915

Sugar ORM doesn't manage 1 to N relationships (the kind of relation you normally resolve with a List). Please check this: https://stackoverflow.com/a/44879733/3891283

Upvotes: 0

Jon Goodwin
Jon Goodwin

Reputation: 9153

Class cannot be read from Sqlite3 database. Please check the type of field myStringList(java.util.List)

The line:

myStringList= new ArrayList<>();

should be:

myStringList= new ArrayList<String>();

Upvotes: 0

Related Questions