Insert an object inside an object using android room persistence library
Asked Answered
J

1

9

Directory

@Entity(tableName = "directory")
class Directory(@PrimaryKey(autoGenerate = false) var id: Int? = null,
                @ColumnInfo(name = DIR_NAME) var dirName: String? = null,
                @Ignore var dirImages: List<Images>? = null

) : Serializable {
    companion object {
        const val DIR_NAME = "dirName"
        const val DIR_IMAGES = "dirImages"
    }
}

Image model

@Entity(foreignKeys = arrayOf(ForeignKey(entity = Directory::class,
        parentColumns = arrayOf("id"),
        childColumns = arrayOf("id"),
        onDelete = ForeignKey.CASCADE)))

data class Images(
        @PrimaryKey(autoGenerate = false) val id: Int? = null,
        @ColumnInfo(name = "image") val images: String
) {

}

Directory Dao

@Dao
interface DirectoryDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(directory: ArrayList<Directory>?)

}

How to insert list of images in directory? Should I create a separate Dao for images?

Jens answered 11/5, 2018 at 9:44 Comment(1)
The closest thing I can suggest is @Transaction annotation.Peon
L
8

Why not make your list of Images a simple list of String ? (you can use typealias in kotlin if you want to stick to image)

You have 2 options, depending on how you need to access your Image Objects. Are you okay to only get the list of Images from your Directory object or you do you need to some queries on your images in the DB? (such as count, findBy etc...)

1st option, if you just want to get your list of Images in your Directory object (probably the best for your case) :

@Entity(tableName = "directory")
class Directory(@PrimaryKey(autoGenerate = false) var id: Int,
                @ColumnInfo(name = DIR_NAME) var dirName: String,
                @ColumnInfo(name = "images")
                @TypeConverters(ImagesConverters::class)
                 var dirImages: List<Images>)

where ImagesConverters.kt :

public class ImagesConverters {

    /**
     * Convert a a list of Images to a Json
     */
    @TypeConverter
    fun fromImagesJson(stat: List<Images>): String {
        return Gson().toJson(stat)
    }

    /**
     * Convert a json to a list of Images
     */
    @TypeConverter
    fun toImagesList(jsonImages: String): List<Images> {
        val notesType = object : TypeToken<List<Images>>() {}.type
        return Gson().fromJson<List<Images>>(jsonImages, notesType)
    }
}

Don't forget to add gson in your gradle file :

implementation 'com.google.code.gson:gson:2.8.4'

In the your table "Directory", it will store the list of images directly into the col "images", in a json format.

2nd option, if you just want to a different table for your images and execute queries on them.

You will need to use a one to many relations and have 3 objects :

// directory.kt
@Entity(tableName = "directory")
class Directory(@PrimaryKey(autoGenerate = false) var id: Int,
                @ColumnInfo(name = DIR_NAME) var dirName: String)


// image.kt
@Entity(tableName = "images")
class Image(@PrimaryKey(autoGenerate = false) var id: Int,
            @ColumnInfo(name ="images") var image: String,
            @ColumnInfo(name ="directoryId") var directoryId: Int)

// directoryWithImages.kt
public class DirectoryWithImages {
   @Embedded
   public Directory directory;

   @Relation(parentColumn = "id", entityColumn = "directoryId", entity = Image.class)
   public List<Image> images;
}

And finally your dao :

@Dao
public interface LoadDirectoryWithImagesDao {
    @Query("SELECT * FROM directory")
    public List<DirectoryWithImages> loadDirectoriesWithImages();
}

Hope this help !

Limnology answered 21/5, 2018 at 16:20 Comment(4)
In addition to option 1, type converters should also be declared on appdatabase -> @TypeConverters(ImagesConverters::class)Jens
is DIR_NAME definedRepresentation
Option 2: How to insert those objects to the db?Maddalena
@Maddalena This would result in two separate inserts. First you insert the directory and then images ie: @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertDirectory(directory: Directory) @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertImages(images: List<Image>)Oily

© 2022 - 2024 — McMap. All rights reserved.