Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Room persistent database - how to insert list of items into DB when it has no primary key related to table

I am having a hard time getting a list item into room. the list item is called measurements and its of type Measurement. the list item has no primarykey that would be related to the database. but i have no problem adding the same primary key for the ProductModel if necessary.

Here is what i have so far:

@Entity(tableName = TABLE_NAME)
public class ProductModel {

    public static final String TABLE_NAME = "product";

    @PrimaryKey
    private int idProduct;

    private int idCategoryDefault;

    @Relation(parentColumn = "idProduct", entityColumn = "idProduct", entity = SortedAttribute.class)
    private List<SortedAttribute> sortedAttributes = null;
}

@Entity
public class SortedAttribute {

    @PrimaryKey
    private int idProduct;

    private String reference;

    @Embedded
    private List<Measurement> measurements = null; //****how do i get this into room ? its a LIST of measurements, not a measurement so calling Embedded i think wont work as it cant flatten it****/
}

public class Measurement {

    private String value;
    private String valueCm;

    public Measurement() {
    }
}
like image 307
j2emanue Avatar asked Jun 29 '17 03:06

j2emanue


People also ask

How do I allow null values in a room database?

In Kotlin, this means that title can never be null. To fix this, you just need to change the Entity class a bit, and allow the fields to be Nullable . val type: Int, val url: String?


2 Answers

Embedded annotation can be used on a POJO or Entity only, not for a List. So, Room can not automatically flatten your list in this case.
You can use TypeConverter to convert List<Measurement> into String(in JSON format) and vise versa. You can use any JSON parser library to support it. For example, I use Gson as following.

public class ProductTypeConverters {
    @TypeConverter
    public static List<Measurement> stringToMeasurements(String json) {
        Gson gson = new Gson();
        Type type = new TypeToken<List<Measurement>>() {}.getType();
        List<Measurement> measurements = gson.fromJson(json, type);
        return measurements;
    }

    @TypeConverter
    public static String measurementsToString(List<Measurement> list) {
        Gson gson = new Gson();
        Type type = new TypeToken<List<Measurement>>() {}.getType();
        String json = gson.toJson(list, type);
        return json;
    }
}

@Entity
@TypeConverters(ProductTypeConverter.class)
public class SortedAttribute {

    @PrimaryKey
    private int idProduct;

    private String reference;

    private List<Measurement> measurements = null; 
}
like image 189
Quang Nguyen Avatar answered Oct 26 '22 02:10

Quang Nguyen


EDIT: Use a type converter

@Relation is what you are looking for.

https://developer.android.com/reference/android/arch/persistence/room/Relation.html

From the Room docs:

@Entity
public class Pet {
     @ PrimaryKey
     int petId;
     String name;
 }
 public class UserNameAndAllPets {
   public int userId;
   public String name;
   @Relation(parentColumn = "petId", entityColumn = "userId")
   public List<Pet> pets;
 }

 @Dao
 public interface UserPetDao {
     @Query("SELECT petId, name from User")
     public List<UserNameAndAllPets> loadUserAndPets();
 }

Note: Upon further research, Room does not quite support lists of objects that are INSIDE objects. I (and others) have opted to handle the lists separately. Room can handle lists of objects just fine as long as they aren't within an object; so as long as your items inside the list are related to your overall object you can recover the list.

So, you would actually @Ignore the list and just handle it in your Dao abstract class. I could not find the SO post's I found earlier that portray this.

like image 4
DeaMon1 Avatar answered Oct 26 '22 02:10

DeaMon1