Room database relation not applying - android

I can't make the relation between these entities.
with SQL query I can make relation but with room not working.
I think this a room bug but don't know why. and taking me a lot of time.
using 2.2.6 version.
#Entity
data class Movie(
#SerializedName("country")
val country: String,
#SerializedName("genres")
val genres: List<String>,
#SerializedName("id")
#PrimaryKey(autoGenerate = false)
val id: Int,
#SerializedName("images")
val images: List<String>? = null,
#SerializedName("imdb_rating")
val imdbRating: String,
#SerializedName("poster")
val poster: String,
#SerializedName("title")
val title: String,
#SerializedName("year")
val year: String
)
#Entity
data class FavoriteMovie(
#PrimaryKey(autoGenerate = false)
val id: Int ,
val movieId: Int,
val createTime:String
)
data class MovieAndFavoriteMovie(
#Embedded val movie: Movie,
#Relation(parentColumn = "id", entityColumn = "movieId")
val favoriteMovie: FavoriteMovie
)
DAO
#Query("SELECT * FROM Movie")
#Transaction
fun getAllFavoriteMovies(): Flow<List<MovieAndFavoriteMovie>>
Error log
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter favoriteMovie
at com.movie_explorer.data.database.MovieAndFavoriteMovie.<init>(Unknown Source:7)
at com.movie_explorer.data.database.dao.FavoriteMovieDao_Impl$5.call(FavoriteMovieDao_Impl.java:166)
at com.movie_explorer.data.database.dao.FavoriteMovieDao_Impl$5.call(FavoriteMovieDao_Impl.java:112)
at androidx.room.CoroutinesRoom$Companion$createFlow$1$1.invokeSuspend(CoroutinesRoom.kt:81)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)

Related

Android Room: Entities and POJOs must have a usable public constructor

I'm trying to save the data class i got from json to room database and suddenly get errors like this while building the app.
Entities and POJOs must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
NewsResponse model object
data class NewsResponse(
val copyright: String,
val response: Response,
val status: String
)
Response object
data class Response(
val docs: List<Docs>
)
Docs object(this is the data class i want to save)
#Entity(
tableName = "docs"
)
data class Docs(
#PrimaryKey(autoGenerate = true)
var id: Int? = null,
val _id: String,
val `abstract`: String,
#Embedded
val byline: Byline,
val document_type: String,
#Embedded
val multimedia: Multimedia,
#Embedded
val headline: Headline,
val lead_paragraph: String,
val news_desk: String,
val pub_date: String,
val section_name: String,
val snippet: String,
val source: String,
val subsection_name: String,
val type_of_material: String,
val uri: String,
val web_url: String,
val word_count: Int
)
Byline object
#Entity
data class Byline(
val original: String
)
Multimedia object
#Entity
data class Multimedia(
val url: String
)
Headline object
#Entity
data class Headline(
val main: String
)
Any ideas how to solve this?

Cant figure out return type of room db

My Entity
#Entity(tableName = "my_entity_table")
internal data class MYEntity(
#PrimaryKey(autoGenerate = true)
val pcID: Int,
val server_id: String,
val name: String,
val detail: String,
val duration: Int,
val start_date : Long,
val end_date: Long,
val created_by_user_id: String,
val db_create_dttm: Long,
val db_update_dttm: Long,
val db_create_src: Long,
val db_update_src: Long
)
My dao query where I to select the duration,start_date and end_date
#Query("select duration,start_date,end_date from my_entity_table where id =:pcID")
suspend fun getDurationDetails(pcID:Int) : What should be the return type?
What should be the return type of the query ??
You could make a specific data class as model for your query with the specific fields:
data class ExampleModel(
#ColumnInfo(name = "duration") val duration: Int?,
#ColumnInfo(name = "start_date") val start_date: Long?
#ColumnInfo(name = "end_date") val end_date: Long?
)
And then use it as return:
#Query("select duration,start_date,end_date from my_entity_table where id =:pcID")
suspend fun getDurationDetails(pcID:Int) : ExampleModel
I don't think that using the Entity model is posible cause your Entity parameters are not nullable and you query just a few of that parameters.

Roomdb - Update #Embedded object within an Entity

I faced a problem when updating values of #Embedded object within an Entity.
Here is my Entity class:
#Entity
data class ReplyData(
#PrimaryKey val id: String,
#ColumnInfo(name = "sequence") val sequence: Int?,
#Embedded(prefix = "from") val from: From? <--- I want to update this #Embedded object within entity
)
#Entity
data class From(
#ColumnInfo(name = "id") val id: String? = "",
#ColumnInfo(name = "name") val name: String? = "",
#ColumnInfo(name = "avatar") val avatar: String? = "",
#ColumnInfo(name = "kind") val kind: String? = ""
)
I want to update these 3 values in 1 shot instead of updating them one-by-one with this query below.
#Query("UPDATE replydata.from SET name = :name, avatar = :avatar, kind = :kind WHERE id = :id")
fun updateReplyData(id: String, name: String, avatar: String, kind: String)
How can I achieve that without affecting the original entity (ReplyData)?
I tried this solution, but it is not working at all:
#Query("SELECT * FROM message WHERE id = :id")
suspend fun getReplyMessage(id: String): Message
#Update(entity = From::class)
suspend fun updateReply(msg: Message)
suspend fun updatePinMessage(id: String, from: From) {
val msg = getReplyMessage(id)
msg.from?.avatar = from.avatar
msg.from?.name = from.name
msg.from?.kind= from.kind
updateReply(msg)
}
Some notes:
#Embedded just shares own fields in the parent.
For instance the data table columns are:
[id | sequence | fromid | fromname | fromavatar | fromkind ]
NB: Better to use "from_" instead "from"
you can update these fields directly in your queries.
Maybe so late but ...
You need create support class
#Entity
data class ReplyData(
#PrimaryKey val id: String,
#ColumnInfo(name = "sequence") val sequence: Int?,
#Embedded(prefix = "from") val from: FromItem <- here
)
#Parcelize
data class FromItem(val item: From)
data class From(
val id: String? = "",
val name: String? = "",
val avatar: String? = "",
val kind: String? = ""
)
and update from
#Query("Update ReplyData set fromitem = :item where id = :id")
fun update(id: Long, item: From)
P.S:
I didn't check this code, maybe it has some errors

Adding a POJO into a Room database table

I have a POJO class OfflineDataRequestInfo which I want to insert into a database table as part of OfflineData which is my entity. but I get an error
How can I fix this please
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. private final com.i6systems.offlineservicelibrary.offlineDatabase.OfflineDataRequestInfo requestInfoJsonX = null;
this is my code
data class OfflineDataRequestInfo (
val status: String,
val userId: String,
val fuelOrderId: String,
val timeStamp: String,
val fuelOrder: String
)
#Entity
data class OfflineData (
#PrimaryKey(autoGenerate = true) val uid: Int = 0,
#ColumnInfo(name = "request_info_json") val requestInfoJson: String?,
#ColumnInfo(name="request_code") val requestCode: String?,
#ColumnInfo(name="request_info_jsonX") val requestInfoJsonX: OfflineDataRequestInfo
)
This is not I insert
suspend fun insertOfflineData(requestInfoJson: String, requestCode: String, offlineDataRequestInfo: OfflineDataRequestInfo): Long {
var result: Long = 0
result = OfflineDatabaseManager.getInstance(app.applicationContext).insertOfflineData(
OfflineData(
0,
requestInfoJson,
requestCode,
offlineDataRequestInfo
))
return result
}
offlineHelper.insertOfflineData(
inPositionApiData.toString(),
"notifyInPosition",
OfflineDataRequestInfo(
"in-position",
action.userId,
id,
action.timestamp.toString(),
fuelOrderData.toString()
))
As i see you have 2 way to solve it :
Write a TypeConverter for your object OfflineDataRequestInfo
Add annotation #Embedded
#Embedded
#ColumnInfo(name="request_info_jsonX")
val requestInfoJsonX: OfflineDataRequestInfo

Android Room - Many-to-many relationship not returning relation entities

I've followed the documentation provided on android developer guides and a Medium article.
I'm trying to return a playlist of songs, but want a list of entities and not just the IDs. Following the above links I have this.
My Entities:
#Entity
data class MediaEntity(
#PrimaryKey val identifier: String,
val imageUrl: String,
val title: String,
val description: String,
val media: String,
val duration: Double,
val progress: Int,
val listenedToCompletion: Boolean
)
#Entity
data class PlaylistEntity(
#PrimaryKey val playlistId: String,
val playlistName: String,
val playlistDescription: String = "",
val currentPosition: Int = 0
)
#Entity(primaryKeys = ["playlistId", "identifier"])
data class PlaylistMediaLinkEntity(
val playlistId: String,
val identifier: String
)
My DAO for the link table is as follows:
#Dao
interface PlaylistMediaLinkDao {
#Transaction
#Query("SELECT * FROM PLAYLISTENTITY")
fun getPlaylistWithMediaItems(): List<MediaInPlaylist>
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(playlistMediaLinkEntity: PlaylistMediaLinkEntity)
}
And then my media in playlist object:
class MediaInPlaylist() {
#Embedded
lateinit var playlist: PlaylistEntity
#Relation(
parentColumn = "playlistId",
entity = MediaEntity::class,
entityColumn = "identifier",
associateBy = Junction(
value = PlaylistMediaLinkEntity::class,
parentColumn = "playlistId",
entityColumn = "identifier"
)
)
lateinit var mediaEntities: List<MediaEntity>
}
I can confirm my PlaylistMediaLinkEntity is populated with playlist-media id pairs, but when calling getAllPlaylistsWithMediaItems, the MediaInPlaylist object is returned with the Playlist data, but the list of mediaEntries is empty.
Have I left something out or where am I going wrong? What I've done matches most examples online.

Categories

Resources