aidanmack
aidanmack

Reputation: 558

Android Room - insert list of sealed classes .. or anything

I have a list of items like the below that I would like to enter into a database using room.

 data class MyRotasDayItem(
 @PrimaryKey
 @SerializedName("id")
 val id: Long,
 @SerializedName("date")
 val date: String,
 @Embedded
 @SerializedName("dayEvents")
 val dayEvents: List<SealedObj>
 )

However I cant seem to add dayEvents. Even if I made the type List I get... Entities and POJOs must have a usable public constructor Do i have to use a type converter?

What if in the list Type is a Sealed class that contain other data objects like...

sealed class MySealedExample(
    open val foo: Long,
    open val bar: Long
) {

    @PrimaryKey(autoGenerate = true)
    var id: Int = 0


    @Entity
    data class AnExample1(
        @Ignore override val foo: Long,
        @Ignore override val bar: Long,
        val something:String
    ) : MySealedExample(foo, bar)

    @Entity
    data class AnExample2(
        @Ignore override val foo: Long,
        @Ignore override val bar: Long,
        val somethingElse:List<SomeObj>
    ) : MySealedExample(foo, bar)
}

Anyway to insert that into the database?

Thankyou

Upvotes: 9

Views: 4455

Answers (2)

Tamim Attafi
Tamim Attafi

Reputation: 2521

To save a sealed class to Room or SQL, whether as an Entity, or as an Embedded object, you need to have one big data class with all the properties, from all the sealed variants. Then use an Enum type to indicate variant type to use later for conversion between domain and data layers, or for indication in your code if you don't use Clean Architecture. Hard, but solid and flexible. I hope Room will have some annotations that can generate such code to get rid of the boilerplate code.

Please check my answer here for the full version with examples: https://stackoverflow.com/a/72535888/9005383

PS: If the link is broken in the future, write a comment and I will write a new example.

Upvotes: 1

Hamza Maqsood
Hamza Maqsood

Reputation: 415

Use type converters, I ran into a similar problem and fixed it using type converters. To convert sealed classes into string and vice versa, I used Gson extension from this gist.

@JvmStatic
@TypeConverter
fun sealedClassToString(sealedClass: SealedClass) : String = GsonExtension.toJson(sealedClass)

@JvmStatic
@TypeConverter
fun sealedClassFromString(sealedClass: String) : SealedClass = sealedClass.let { GsonExtension.fromJson(it) }

Upvotes: 4

Related Questions