Reputation: 558
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
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
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