Many to many android room ref extra variable - android

I have a Many to Many relationship set up on my Room database denoted by the following diagram:
eveything works great but I would like to make the following addition:
My question is how do I go about having RecipeWithIngredients get this unit:String variable from the RecipeIngredientRef Entity when a recipeWithIngredients is constructed on a query?
#Entity(indices = [Index(value = ["name"],unique = true)])
data class Recipe(
var name: String,
val image: String?
) {
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "recipeID")
var ID: Long = 0
}
#Entity(indices = [Index(value = ["name"],unique = true)])
data class Ingredient(
val name: String,
val image: String?,
val amount: Int
) {
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "ingredientID")
var ID: Long = 0
}
#Entity(primaryKeys = ["recipeID", "ingredientID"])
data class RecipeIngredientRef(
val recipeID: Long,
val ingredientID: Long,
val unit: String
)
data class RecipeWithIngredients(
#Embedded
val recipe: Recipe,
#Relation(
parentColumn = "recipeID",
entity = Ingredient::class,
entityColumn = "ingredientID",
associateBy = Junction(
value = RecipeIngredientRef::class,
parentColumn = "recipeID",
entityColumn = "ingredientID"
)
)
val ingredients: List<Ingredient>
)

As far as I know there is no built-in way using current many-to-many Relations in Room for that. So I just want to save your time for researches.
This RecipeIngredientRef table is used internally just for two other tables' join and for now adding there additional fields will not help to get these fields with #Relations/Junction mechanism.
You can try workarounds, but they are no so elegant and they needed to dig deeper into Room's result's processing:
Don't use #Relation/Junction mechanism for RecipeWithIngridients at all, write your own query with two JOINs (since you should get data from 3 tables). As a result you'll get some raw set of records and then you should use loops and methods of Kotlin collections to turn result into needed form.
Use #Relation/Junction mechanism, but after getting result - make additional processing of result - make one more query to RecipeIngredientRef table and set missing unit value manually (again with loops and methods of Kotlin collections).

Related

What do #Relation classes mean when creating a one-to-many relationship in Room?

I'm making an Workout log app.
One Workout has multiple sets.
I want to store this in a one-to-many relationship in Room.
In conclusion, I succeeded in saving, but I'm not sure what one class does.
All of the other example sample code uses this class, so I made one myself, but it doesn't tell me what it means.
WorkoutWithSets
data class WorkoutWithSets(
#Embedded val workout: Workout,
#Relation (
parentColumn = "workoutId",
entityColumn = "parentWorkoutId"
)
val sets: List<WorkoutSetInfo>
)
The following two entity classes seem to be sufficient to express a one-to-many relationship. (Stored in Room)
Workout
#Entity
data class Workout(
#PrimaryKey(autoGenerate = true)
var workoutId: Long = 0,
var title: String = "",
var memo: String = "",
)
It seems that the following two entity classes are sufficient enough to store a one-to-many relationship.. (stored in Room)
WorkoutSetInfo
#Entity(
foreignKeys = [
ForeignKey(
entity = Workout::class,
parentColumns = arrayOf("workoutId"),
childColumns = arrayOf("parentWorkoutId"),
onDelete = ForeignKey.CASCADE
)
]
)
data class WorkoutSetInfo(
#PrimaryKey(autoGenerate = true)
val id: Long = 0,
val set: Int,
var weight: String = "",
var reps: String = "",
var unit: WorkoutUnit = WorkoutUnit.kg,
val parentWorkoutId: Long = 0
)
Even if the WorkoutWithSet class does not exist, the Workout and WorkoutSetInfo classes are stored in Room.
What does WorkoutWithSets class mean? (or where should I use it?)
What does WorkoutWithSets class mean?
It is a class that can be used to retrieve a Workout along with all the related WorkoutSetInfos via a simple #Query that just retrieves the parent Workouts.
What Room does is add an additional query that retrieves the children (WorkoutSetInfo's) for each Workout.
The result being a list of WorkOutWithSets each element (a Workout) containing/including a list of all the related WorkoutSetInfo's.
You would use this when you want to process a Workout (or many Workouts) along with the related WorkoutSetInfo's (aka the child WorkoutSetInfo's for the parent Workout).
What Room does is consider the type (objects) to be returned.
So if you had
#Query("SELECT * FROM workout")
fun getJustWorkouts(): List<Workout>
then the function would return just a list of Workout objects.
But if you had
#Query("SELECT * FROM workout")
fun getWorkoutsWithSets(): List<WorkoutWithSets>
then the function would return a list of WorkoutWithSets and thus the parent Workouts with the child WorkoutSetInfo's.
What Room does is build and execute an underlying query, for eack Workout extracted, along the lines of "SELECT * FROM workoutInfoSet WHERE workout.workoutId = parentWorkoutId" and hence why it suggests the use of the #Transaction annotation (the build will include a warning if #Transaction is not coded).

Room database query for several Entities

Could you please help me? I try to get data from TMDB via Retrofit2 to Room database and display it in Recyclerview. I make 3 api calls to get data about popular movie id/poster/overview/title/genres, with the second call I get movie duration by movie id, and with the 3rd call I get movie cast by movie id.
#GET("movie/popular")
suspend fun getPopularMovies(#Query("api_key") apiKey: String?): PopularResponseModel
#GET("/movie/{movie_id}")
suspend fun getMovieDuration(#Query("api_key") apiKey: String?): MovieDuration
#GET("/movie/{movie_id}/credits")
suspend fun getCrewAndCast(#Query("api_key") apiKey: String?): Cast
And I get 3 models:
#Entity(tableName = "movie")
data class MovieResponse(
#PrimaryKey(autoGenerate = false)
#ColumnInfo(name = "movie_id")
val id: Int,
#ColumnInfo(name = "movie_image")
val poster_path: String,
#ColumnInfo(name = "movie_overview")
val overview: String,
#ColumnInfo(name = "movie_title")
val title: String,
#ColumnInfo(name = "movie_genres")
val genre_ids: ArrayList<Int>)
#Entity(tableName = "movie_duration")
data class MovieDuration(
#PrimaryKey(autoGenerate = false)
#ColumnInfo(name = "movie_id")
val id: Int,
#ColumnInfo(name = "duration")
val runtime: Int
)
#Entity(tableName = "cast")
data class Cast(
#PrimaryKey(autoGenerate = false)
#ColumnInfo(name = "movie_id")
val id : Int,
val cast :ArrayList<Cast>
)
The first question is how do I make a #Query request (in the #Dao interface) that will help me to display the popular movie name, title, genre + movie duration associated with that movie in a Recyclerview. I guess they should be mapped somehow by movie id...
For example (John Wick - Action/crime, 2h 10m).
The second question is how to make a #Query request that will help me to associate the exact movie I click on with the movie cast?
(movie John Wick - John Wick: Keanu Reeves...)
The first question is how do I make a #Query request (in the #Dao interface) that will help me to display the popular movie name, title, genre + movie duration associated with that movie in a Recyclerview. I guess they should be mapped somehow by movie id...
As there is a one to one relationship between movie and it's duration then you could simplify matters by including the duration field in the movie. For example instead of MovieResponse and MovieDuration have just MovieResponse as:-
#Entity(tableName = "movie")
data class MovieResponse(
#PrimaryKey(autoGenerate = false)
#ColumnInfo(name = "movie_id")
val id: Int,
#ColumnInfo(name = "movie_image")
val poster_path: String,
#ColumnInfo(name = "movie_overview")
val overview: String,
#ColumnInfo(name = "movie_title")
val title: String,
#ColumnInfo(name = "movie_genres")
val genre_ids: ArrayList<Int>,
#ColumnInfo(name = "duration")
val runtime: Int
)
Otherwise you would typically have a POJO class that reflects the two clasess/entities/tables that has two fields; one a MovieResponse and the other a MovieDuration.
e.g.
Option 1 (via #Embedded annotation):-
data class MovieWithEmbeddedDuration(
#Embedded
val movieResponse: MovieResponse,
#Embedded(prefix = "duration_") /* prefix required to disambiguate movie_id column that is in both */
val movieDuration: MovieDuration
)
This would require the use of a JOIN such as #Query("SELECT movie.*, movie_duration.movie_id AS duration_movie_id, movie_duration.duration AS duration_duration FROM movie JOIN movie_duration ON movie.movie_id = movie_duration.movie_id") fun getMoviesWithEmbeddedDuration(): List<MovieWithEmbeddedDuration>
note the complexity due to the need to disambiguate the movie_id column which appears in both tables. AS is used to alter the name of the column when it is output (much easier to have unique column names, as the movie_id is a reference/map/relation to the parent perhaps name the column movie_id_map which better describes the column's usage).
Option 2 (via #Relation annotation)
data class MovieWithRelatedDuration(
#Embedded
val movieResponse: MovieResponse,
#Relation(
entity = MovieDuration::class,
parentColumn = "movie_id",
entityColumn = "movie_id"
)
val movieDuration: MovieDuration
)
this doesn't require the join you simple use a query to get the parent(s) BUT get the POJO with #relation e.g. #Transaction #Query("SELECT * FROM movie") fun getMoviesWithRelatedDuration(): List<MovieWithRelatedDuration>
Here #Relation does the work BUT it works by running separate queries to get the children (mimicking the JOIN), hence why the #Transaction annotation (not needed but warned if omitted). Thus this is less efficient.
Option 2 (via field for the duration)
Instead of embedding the MovieDuration object, you could extract just the duration and have a field for that e.g.
data class MovieWithDurationAsField(
#Embedded
val movieResponse: MovieResponse,
val duration: Int
)
This could be used using #Query("SELECT movie.*,duration FROM movie JOIN movie_duration ON movie_duration.movie_id = movie.movie_id") fun getMoviesWithDurationAsField(): List<MovieWithDurationAsField>
A JOIN is used so this is efficient not that the value for the field is determined according to the column that matches it's name. So if runtime were used then you'd have to rename the output column from duration to runtime.
The second question is how to make a #Query request that will help me to associate the exact movie I click on with the movie cast?
This has basically been explained above (see Option 2). Create the POJO with the parent #Embedded and the children with #Relation annotation and the val being a List/Array of the child objects rather than a single object.
e.g. something like:-
data class MovieWithCastList(
#Embedded
val movieResponse: MovieResponse,
#Relation(
entity = Cast::class,
parentColumn = "movie_id",
entityColumn = "movie_id"
)
val castList: List<Cast>
)
The Query/function would be along the lines of #Query("SELECT * FROM movie") fun getMovieWithCastList(): List<MovieWithCastList>
Note obviously with Retrofit you adapt the queries accordingly.

Saving Multiple Nested lists into room database

I'm working on dictionnary application in which the api request have many nested lists , i have tried to insert all the nested lists but i'm getting different error each time , i would like to know what is the best way to save multiple nested lists , should i use room relations or something else , thank you in advance for help , i m really stuck with this for few days now
This is sample schema of how are the lists nested
This is the parent list
#Entity(tableName = "DICTIONNARYTABLE")
#TypeConverters(DictionnaryModelConverter::class)
class DictionnaryModel : ArrayList<DictionnaryModelItem>() {
#PrimaryKey(autoGenerate = true)
#NotNull
val wordId: Long = 0
}
The parent list has two lists as well
#Entity
data class DictionnaryModelItem(
#PrimaryKey val dictionnaryModelId: Long = 0,
#TypeConverters(DictionnaryMeaningConverter::class)
val meanings: MutableList<Meaning>,
#TypeConverters(DictionnaryPhoneticsConverter::class)
val phonetics: MutableList<Phonetic>,
val word: String
)
//---------------------------
#Entity
data class Meaning(
#PrimaryKey val meaningId: Long = 0,
#TypeConverters(DictionnaryDefinitionConverter::class)
val definitions: List<Definition>,
val partOfSpeech: String
)
///-------------------------------
#Entity
data class Phonetic(
#PrimaryKey val phoneticId: Long = 0,
val audio: String,
val text: String
)
inside the meaning , i also have definition which another model
#Entity
data class Definition(
#PrimaryKey val definitionId: Long = 0,
val definition: String,
val example: String,
#TypeConverters(DictionnarySynonymsConverter::class)
val synonyms: List<String>
)
You need to create one-to-many relationship data model here. For instance each dictionary word has many meanings and many phonetics. Here Dictionary is a parent entity and Meaning and Phonetic are the child entities. Each child entity will have it's parent entity primary key stored in its table. You will need another data class to define this relationship.
data class DictionaryWithMeanings(
#Embedded val dictionary: Dictionary,
#Relation(
parentColumn = "dictionaryModelId",
entityColumn = "dictionaryId"
)
val meanings: List<Meaning>
)
Meaning table has to store dictionaryId as foreign key its table. Same has to be defined for phonetics. And Meaning table again has similar relationship with Definition and so on.

Find entity with many-to-one relationship uses wrong id for query parameter

Look guys, I need some help with Room on Android.
In my project there are two entities, Item and Unit of Measure. The item can be in only one unit of measure but the unit of measure can be in several units.
As the project's interest is to deal with the Item, it would need to have a many-to-one relationship and as Room doesn’t deal with that, I chose to set up a many-to-many relationship and create just one Entity for cross-reference that present the meaning contrary.
The database is already started with 4 units of measurement, Kg, g, L and cm, so the total number of records is 4, the ids are 1, 2, 3 and 4 respectively.
When I insert the first item in the database with a Unit of Measure equal to Kg, it will have Id = 1 (because it was the first record) and when I search for it informing id 1, everything is ok, it works perfectly, it returns the item with the Unit of Measure Kg.
When I register the second item (so now this new item will have id 2) also with the Unit of Measurement equal to Kg there, problems begin to appear. When performing his search informing his id which is 2 he returns the item but as the Unit of Measure equal to g (gram) which is also code 2.
That is, when Room is going to mount the result of the item searched for, the Code of the Unit of Measure is being considered the same code as the Item.
Room doesn't seem to be looking at the id of the relationship I created for the Item with Unit of Measure, but I'm not doing it right, or I'm the one who forgot something.
ItemEntity
#Entity(
tableName = "item"
)
data class ItemEntity(
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "item_id")
var itemID: Long = 0,
#ColumnInfo(name = "description")
var description: String = "",
#ForeignKey(
entity = ComparationEntity::class,
parentColumns = ["comparation_id"],
childColumns = ["fk_comparation_id"],
onDelete = ForeignKey.CASCADE
)
#ColumnInfo(name = "fk_comparation_id")
var fkComparationID: Long = 0,
#ColumnInfo(name = "price")
private var price: Double = 0.0,
#ColumnInfo(name = "quantity")
var quantity: Double = 0.0,
#Ignore
private var priceUnit: Double = 0.0
) {
fun setPrice(price: Double) {
if (this.quantity.toFloat() != 0.00f && price.toFloat() != 0.00f) {
priceUnit = this.price.div(this.quantity)
}
}
fun getPrice() = price
fun getPriceUnit(): Double {
return priceUnit
}
}
UnitMeasureEntity
#Entity(
tableName = "unit_measure"
)
data class UnitMeasureEntity(
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "un_meas_id")
var unMeasID: Long = 0,
val description: String,
val acronym: String,
val symbol: String
)
RelationItemWithUnits
#Entity(tableName = "relation_item_whit_units", primaryKeys = ["item_id", "un_meas_id"])
data class RelationItemWithUnits(
#ColumnInfo(name = "item_id")
val itemID : Long,
#ColumnInfo(name = "un_meas_id")
val unMeasID : Long
)
ItemWithUnitMeasure
data class ItemWithUnitMeasure(
#Embedded
var item: ItemEntity,
#Relation(
entity = UnitMeasureEntity::class,
parentColumn = "item_id",
entityColumn = "un_meas_id",
associateBy = Junction(RelationItemWithUnits::class)
)
var unitMeasureWithMeasureType: UnitMeasureWithMeasureType
)
RelationsUnitsWithMeasuresType
#Entity(tableName = "relation_units_whit_measure_type", primaryKeys = ["un_meas_id", "measure_type_id"])
data class RelationsUnitsWithMeasuresType(
#ColumnInfo(name = "un_meas_id")
val unMeasID: Long,
#ColumnInfo(name = "measure_type_id")
val measureTypeID : Long
)
it would need to have a many-to-one relationship and as Room doesn’t deal with that, I chose to set up a many-to-many relationship and create just one Entity for cross-reference that present the meaning contrary
I think you've got into misconception there. Room's documentation really doesn't include any many-to-one relations. But many-to-one relation is the same as one-to-many in table's structure sense. Let's say you have table A and table B, and table A has many rows with the same id from the table B. As such tables hold one-to-many relation.
If you want to get all rows from A table and to attach there value from B table, you can use one-to-one relation from Room's documentation. Since one row from A has a relation only with one row from B.
If you want to get all rows from B table and to attach list of binded values from A table, you can use one-to-many relation. Since one row from B table has a relation with many rows from A.
So you don't need to use separate table and many-to-many relations here.
It would be much easier just to add unitMeasureId to ItemEntity table and then use one-to-one relation to get needed result.

"no such column" SQL error from Android Room and multiple #Embedded fields on POJO

The original question is at the very bottom. I have created a minimal (non-)working example of my problem which is hopefully easier to read through. The example is here at gitlab. There is a readme describing the problem. I am pasting some parts of the project here.
The data model is plain simple:
Owner <--(1:N)-- Child --(N:1)--> ReferencedByChild
All I want to do is to read an Owner from the database with all its associated Child objects and for each Child object
also the ReferencedByChild object that it references.
The whole code that reproduces my problem is below. What I am not 100% sure about is the #Relation on the OwnerWithEverything POJO. See below please.
#Database(
entities = [
Owner::class,
Child::class,
ReferencedByChild::class
],
version = 1
)
abstract class AppDatabase : RoomDatabase() {
abstract fun appDao(): AppDao
}
#Dao
abstract class AppDao {
#Insert
abstract fun insertOwner(owner: Owner): Long
#Insert
abstract fun insertChild(child: Child): Long
#Insert
abstract fun insertReferencedByChild(referencedByChild: ReferencedByChild): Long
#Query("SELECT * FROM Child INNER JOIN ReferencedByChild ON Child.referencedByChildId = ReferencedByChild.refByChildId ORDER BY Child.childText")
abstract fun findAllChildrenWithReferencedClasses(): List<ChildWithReferenced>
// Commenting this query out makes the build pass, so something here is incorrect.
#Query("SELECT * FROM Owner")
abstract fun findOwnersWithEverything(): List<OwnerWithEverything>
}
// ENTITIES
#Entity
data class Owner(
#PrimaryKey(autoGenerate = true)
val ownerId: Long,
val ownerText: String
)
#Entity(
foreignKeys = [
ForeignKey(
entity = Owner::class,
parentColumns = arrayOf("ownerId"),
childColumns = arrayOf("referencedOwnerId"),
onDelete = ForeignKey.CASCADE
),
ForeignKey(
entity = ReferencedByChild::class,
parentColumns = arrayOf("refByChildId"),
childColumns = arrayOf("referencedByChildId"),
onDelete = ForeignKey.CASCADE
)
]
)
data class Child(
#PrimaryKey(autoGenerate = true)
val childId: Long,
val childText: String,
val referencedOwnerId: Long,
val referencedByChildId: Long
)
#Entity
data class ReferencedByChild(
#PrimaryKey(autoGenerate = true)
val refByChildId: Long,
val refText: String
)
// POJOS
// The Child has exactly one ReferencedByChild reference. This POJO joins those two
class ChildWithReferenced(
#Embedded
var child: Child,
#Embedded
var referencedByChild: ReferencedByChild
)
class OwnerWithEverything {
#Embedded
var owner: Owner? = null
#Relation(
parentColumn = "ownerId",
entityColumn = "referencedOwnerId",
entity = Child::class // which entity should be defined here?
)
var childrenWithReferenced: List<ChildWithReferenced>? = null
}
Building this code results in this error message:
error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: refByChildId)
I think that the Owner query is badly constructed, but I am not entirely sure. If that is the problem, what is the correct way to construct the query?
This is the original question
I have a nested POJO structure that should represent a single Game having multiple Rounds and each Round has a single Topic associated with it:
class GameWithRounds {
#Embedded
var game: Game? = null
#Relation(
parentColumn = "id",
entityColumn = "gameId",
entity = RoundRoom::class
)
var rounds: List<RoundWithTopic>? = null
}
class RoundWithTopic(
#Embedded
var round: RoundRoom,
#Embedded(prefix = "topic_")
var topic: Topic
)
The embedded annotation on Topic specifies a prefix because there are clashing id properties.
The Room Query that can fetch those classes is:
#Query("SELECT Topic.id as topic_id, Topic.name as topic_name, (...), RoundRoom.* FROM RoundRoom INNER JOIN Topic ON RoundRoom.topicId = Topic.id")
abstract fun findRoundsWithTopics(): List<RoundWithTopic>
However, building the project gives me Room errors:
There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such column: topic_id)
Even though when I induce a warning about which fields are actually present, this is what Room tells me:
Columns returned by the query: topic_id, topic_name, topic_description, topic_language, topic_keywords, topic_sourceUrls, topic_furtherUrls, topic_questions, order, gameId, topicId, status, id. Fields in cz.melkamar.sklapecka.model.RoundWithTopic: order, gameId, topicId, status, id, topic_id, topic_name, topic_description, topic_language, topic_keywords, topic_sourceUrls, topic_furtherUrls, topic_questions, topic_image.
The topic_id column is there in the query result! Why am I getting this error?
For completeness, this is the entities:
#Entity
data class Game(
#PrimaryKey(autoGenerate = true)
val id: Long = 0,
#Embedded
val gameConfigurationEmbed: GameConfigurationEmbed
)
data class GameConfigurationEmbed(
var secondsPerTurn: Int,
var maxSecondsPerTurn: Int,
var bonusSecondsPerAnswer: Int
)
#Entity(
foreignKeys = [
ForeignKey(
entity = Game::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("gameId"),
onDelete = ForeignKey.CASCADE
),
ForeignKey(
entity = Topic::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("topicId"),
onDelete = ForeignKey.CASCADE
)
]
)
#TypeConverters(RoomConverters::class)
data class RoundRoom(
val order: Int,
var gameId: Long,
val topicId: String,
var status: RoundStatus = RoundStatus.CREATED,
#PrimaryKey(autoGenerate = true)
val id: Long = 0
) {
enum class RoundStatus {
CREATED, UPCOMING, IN_PROGRESS, FINISHED
}
}
#Entity
data class Topic(
#PrimaryKey val id: String,
val name: String,
val description: String,
val language: String,
val keywords: List<String>,
val sourceUrls: List<String>,
val furtherUrls: List<String>,
val questions: List<String>,
val image: ByteArray?
)
After some research, specifically looking at this link : How can I represent a many to many relation with Android Room?
the only answers we found would be to
either create a hand-made sql query to handle this type of situation
where you have a many-to-many relationship
OR
to alternatively have an additional joining entity which gets
updated as the rest of the objects are updated. With this approach, you can get the ID's and then create additional queries as needed
It seems embedded fields and type converter is not properly used on observing the question. I don't want to go in detail in the solution of the question since it is trying to use complex relations and I cannot test it replicating in my machine.
But I want to provide insight on using Embedded fields and TypeConverter.
Let's take an example from the question above:
Game table has fields
id, secondsPerTurn, maxSecondsPerTurn, bonusSecondsPerAnswer.
It is okay to create entity like below.
#Entity
data class Game(
#PrimaryKey(autoGenerate = true)
val id: Long = 0,
#Embedded
val gameConfigurationEmbed: GameConfigurationEmbed
)
data class GameConfigurationEmbed(
var secondsPerTurn: Int,
var maxSecondsPerTurn: Int,
var bonusSecondsPerAnswer: Int
)
Here in the SQLite table, data is actually stored in four different columns but Room does CRUD operation based on data class structure giving higher feasibilty to the developers.
TypeConverter
Type converter will be helpful if we want to store non primitive data types or same type of data which will not be covered by #Embedded.
For example, a football game can be held in two places: home and away. Home and Away can have the same field names like placeName, latitude, longitude. In this case, we can create data class and type converters like below:
data class GamePlace(
val placeName:String,
val latitude:String,
val longitude:String
)
#Entity
data class Game(
#PrimaryKey(autoGenerate = true)
val id: Long = 0,
#Embedded
val gameConfigurationEmbed: GameConfigurationEmbed
#TypeConverters
var home: GamePlace? = null,
#TypeConverters
var away: GamePlace? = null,
)
object Converters {
private val gson = Gson()
#TypeConverter
#JvmStatic
fun fromGamePlace(gamePlace: GamePlace?): String? {
return if (gamePlace == null) null else gson.toJson(gamePlace)
}
#TypeConverter
#JvmStatic
fun toGamePlace(jsonData: String?): GamePlace? {
return if (jsonData.isNullOrEmpty()) null
else gson.fromJson(jsonData, object : TypeToken<GamePlace?>() {}.type)
}
}
While using type converter, converter class should be defined in database class as below:
#Database(
entities = [Game::class /* ,more classes here*/],
version = 1
)
#TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun gameDao(): GameDao
//.....
}
I hope this will help to deal with Embedded and TypeConverter in Room.

Categories

Resources