Home > Mobile >  How to save List<Double> to Room database?
How to save List<Double> to Room database?

Time:11-12

I'm trying to save a List of Double to Room database using this Converter class:

public class Converters {

    @TypeConverter
    public static String fromDoubleList(List<Double> doubleList){

        Gson gson = new Gson();
        String json = gson.toJson(doubleList);
        return json;
    }

    public static List<Double> fromString(String value){

        Type listType = new TypeToken<List<Double>>(){}.getType();
        return new Gson().fromJson(value, listType);
    }
}

but I keep getting this message:

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.

Why isn't the converter class working?

Edit - This is my database:

@Database(entities = {MarketUnit.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class MarketDatabase extends RoomDatabase {

    public static final String DATABASE_NAME = "market_db";

    private static MarketDatabase instance;

    public static MarketDatabase getInstance(final Context context){
        if(instance == null){
            instance = Room.databaseBuilder(
                    context.getApplicationContext(),
                    MarketDatabase.class,
                    DATABASE_NAME
            ).build();
        }
        return instance;
    }

    public abstract MarketDao getMarketDao();

}

I've tried the suggestion from the duplicate question, but it's not working!

CodePudding user response:

In short you cannot have an Array/List directly as a column.

What you can do is have a POJO as a holder class and then have the column use that type.

e.g.

class Holder() {
   List<Double> doubleList;
}

and in the Entity class have something like

Holder theColumn;

Noting that the Type Converter would then be from/to Holder

e.g. :-

class Converters {

    @TypeConverter
    public String fromHolder(Holder h) {
        Gson gson = new Gson();
        String json = gson.toJson(h);
        return json;
    }
    @TypeConverter
    public Holder toHolder(String s) {
        return new Gson().fromJson(s, Holder.class);
    }
}

Working Example:

Holder :-

class Holder {
    public List<Double> doubles;
}

MarketUnit :-

@Entity
class MarketUnit {
    @PrimaryKey
    Long id = null;
    Holder doubleList;
}

Converters :-

class Converters {

    @TypeConverter
    public static String fromHolder(Holder h) {
        Gson gson = new Gson();
        String json = gson.toJson(h);
        return json;
    }
    @TypeConverter
    public static Holder toHolder(String s) {
        return new Gson().fromJson(s, Holder.class);
    }
}
  • made static so can be called

MarketDao :-

@Dao
abstract class MarketDao {

    @Insert
    abstract long insert(MarketUnit marketUnit);
    @Query("SELECT * FROM marketunit")
    abstract List<MarketUnit> getAllMarketUnits();

}

MarketDatabase :-

@Database(entities = {MarketUnit.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class MarketDatabase extends RoomDatabase {

    public static final String DATABASE_NAME = "market_db";

    private static MarketDatabase instance;

    public static MarketDatabase getInstance(final Context context){
        if(instance == null){
            instance = Room.databaseBuilder(
                    context.getApplicationContext(),
                    MarketDatabase.class,
                    DATABASE_NAME
            ).allowMainThreadQueries().build();
        }
        return instance;
    }

    public abstract MarketDao getMarketDao();

}
  • .allowMainThreadQueries added for brevity and convenience

Finally an Activity MainActivity for test:-

public class MainActivity extends AppCompatActivity {

    MarketDatabase db;
    MarketDao dao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        db = MarketDatabase.getInstance(this);
        dao = db.getMarketDao();

        MarketUnit mu1 = new MarketUnit();
        Holder h = new Holder();
        ArrayList<Double> dbls = new ArrayList<>();
        dbls.add(200.01);
        dbls.add(111.111);
        h.doubles = dbls;
        mu1.doubleList = h;
        dao.insert(mu1);

        for(MarketUnit mu: dao.getAllMarketUnits()) {
            Log.d("DBINFO","MarketUnit ID = "   mu.id);
            Log.d("DBINFO","Converted Holder :-\n\t"   Converters.fromHolder(mu.doubleList));
            for(Double d: mu.doubleList.doubles) {
                Log.d("DBINFO","\tDouble is "   d);
            }
        }
    }
}

Result from the Log :-

2021-11-12 16:34:37.776  D/DBINFO: MarketUnit ID = 1
2021-11-12 16:34:37.777  D/DBINFO: Converted Holder :-
        {"doubles":[200.01,111.111]}
2021-11-12 16:34:37.777  D/DBINFO:  Double is 200.01
2021-11-12 16:34:37.777  D/DBINFO:  Double is 111.111

The MarketUnit table using App Inspection :-

enter image description here

  • Related