I'm trying to load entity sublist, but i would like to avoid to do 2 queries.
I'm thinking about do query inside TypeConverter, but i really don't know if it's good idea.
My entities:
@Entity
class Region(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
var name: String = "",
var locales: List<Locale> = listOf())
@Entity(foreignKeys = arrayOf(ForeignKey(
entity = Region::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("regionId"),
onDelete = CASCADE,
onUpdate = CASCADE
)))
class Locale(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
var regionId: Int = 0,
var name: String = "")
DAOs :
@Dao
interface RoomRegionDao{
@Insert
fun insert(region: Region)
@Delete
fun delete(region: Region)
@Query("select * from region")
fun selectAll(): Flowable<List<Region>>
}
@Dao
interface RoomLocaleDao{
@Insert
fun insert(locale: Locale)
@Query("select * from locale where regionId = :arg0")
fun selectAll(regionId: Int): List<Locale>
}
Database:
@Database(entities = arrayOf(Region::class, Locale::class), version = 1)
@TypeConverters(RoomAppDatabase.Converters::class)
abstract class RoomAppDatabase : RoomDatabase() {
abstract fun regionDao(): RoomRegionDao
abstract fun localeDao(): RoomLocaleDao
inner class Converters {
@TypeConverter
fun toLocales(regionId: Int): List<Locale> {
return localeDao().selectAll(regionId)
}
@TypeConverter
fun fromLocales(locales: List<Locale>?): Int {
locales ?: return 0
if (locales.isEmpty()) return 0
return locales.first().regionId
}
}
}
It's not working because can't use inner class as converter class.
RoomRegionDao.selectAll
?I think that TypeConverter
only works for static methods.
I say this based on the example from here and here
From the relationships section here:
"Because SQLite is a relational database, you can specify relationships between objects. Even though most ORM libraries allow entity objects to reference each other, Room explicitly forbids this."
So I guess it's best if you add @Ignore
on your locales
property and make a method on RoomLocaleDao
thats insert List<Locale>
and call it after insert Region.
The method that inserts a Region can return the inserted id.
If the @Insert method receives only 1 parameter, it can return a long, which is the new rowId for the inserted item. If the parameter is an array or a collection, it should return long[] or List instead. (https://developer.android.com/topic/libraries/architecture/room.html#daos-convenience)
You can get all your Regions
wit a list of Locales
inside each Region
just with one Query
.
All you need to do is create a new Relation
like this:
data class RegionWithLocale(
@Embedded
val region: Region,
@Relation(
parentColumn = "id",
entity = Locale::class,
entityColumn = "regionId"
)
val locales: List<Locale>
)
And latter get that relation in your Dao
like this:
@Query("SELECT * FROM region WHERE id IS :regionId")
fun getRegions(regionId: Int): LiveData<RegionWithLocale>
@Query("SELECT * FROM region")
fun getAllRegions(): LiveData<List<RegionWithLocale>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With