问题
I am implementing a local cache using Room. I have created typeconverter to convert list of objects to json and back. But I am receiving mapping issue while retrieving data from json with error:
The columns returned by the query does not have the fields [title,media] in
com.example.theApp.data.FlickrImage even though they are annotated as non-null or
primitive. Columns returned by the query: [items]
Another one like this:
error: Cannot figure out how to read this field from a cursor.
private final com.example.theApp.data.Media media = null;
I tried other answers here but its not associated directly with this issue.
Here is my typeconverter:
class FlickrImageConverters {
@TypeConverter
fun fromImageListToJson(stat: List<FlickrImage>): String {
return Gson().toJson(stat)
}
/**
* Convert a json to a list of Images
*/
@TypeConverter
fun fromJsonToImagesList(jsonImages: String): List<FlickrImage> {
val type = object : TypeToken<List<FlickrImage>>() {}.type
return Gson().fromJson<List<FlickrImage>>(jsonImages, type)
}
}
Here is my entity class:
@Entity
data class DatabaseImagesEntity(
@PrimaryKey
@TypeConverters(FlickrImageConverters::class)
@SerializedName("item")
val items: List<FlickrImage>)
Dao class @Dao interface ImagesDao {
@Query("select * from DatabaseImagesEntity")
fun getImages(): List<FlickrImage>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(images: List<FlickrImage>)
}
FlickrImage class
data class FlickrImage(val title: String, val media: Media)
Media class
data class Media(val m: String)
LatestImage class
data class LatestImages(val items: List<FlickrImage>)
Please let me know if you faced this issue and if you know the solution for this.
Room database implementation
@Database(entities = [DatabaseImagesEntity::class], version = 1,
exportSchema = false)
@TypeConverters(FlickrImageConverters::class)
abstract class FlickrDatabase: RoomDatabase() {
abstract val imagesDao: ImagesDao
}
private lateinit var INSTANCE: FlickrDatabase
fun getDatabase(context: Context): FlickrDatabase{
synchronized(FlickrDatabase::class.java){
if(!::INSTANCE.isInitialized){
INSTANCE = Room.databaseBuilder(context.applicationContext,
FlickrDatabase::class.java,
"flickerImages").build()
}
}
return INSTANCE
}
回答1:
The issue was I was saving data in the wrong entity, wrong TypeConverters and as a result, I was using the wrong Entity class at the time of database creation.
Here are the necessary changes I had to make to store the list of objects:
Flickr data class
@Entity(tableName = "FlickerImage")
data class FlickrImage(
@PrimaryKey(autoGenerate = true)
val id: Int,
val title: String,
@TypeConverters(MediaConverter::class)
val media: Media)
TypeConvertors for Media class
class MediaConverter {
@TypeConverter
fun fromMediaToJson(stat: Media): String {
return Gson().toJson(stat)
}
/**
* Convert a json to a list of Images
*/
@TypeConverter
fun fromJsonToMedia(jsonImages: String): Media {
val type = object : TypeToken<Media>() {}.type
return Gson().fromJson<Media>(jsonImages, type)
}
}
DAO class
@Dao
interface ImagesDao {
@Query("select * from FlickerImage")
fun getImages(): LiveData<List<FlickrImage>>
Database class
@Database(entities = [FlickrImage::class], version = 1, exportSchema = false)
@TypeConverters(MediaConverter::class)
abstract class FlickrDatabase: RoomDatabase() {
abstract val imagesDao: ImagesDao
}
private lateinit var INSTANCE: FlickrDatabase
fun getDatabase(context: Context): FlickrDatabase{
synchronized(FlickrDatabase::class.java){
if(!::INSTANCE.isInitialized){
INSTANCE = Room.databaseBuilder(context,
FlickrDatabase::class.java,
"flickerImages").build()
}
}
return INSTANCE
}
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(images: List<FlickrImage>)
}
回答2:
You need to add the appropriate annotations to your data class - e.g. for Gson you need to add the annotations @SerializedName("field_name")
Otherwise, there's no way for the converters to know how to translate the json.
To clarify, the current annotations you have are only for Room. Just check with whatever json library you are using for the necessary logic.
回答3:
@Entity(tableName = "images")
data class DatabaseImagesEntity(
@PrimaryKey(autoGenerate = true)
var id: Int? = 0,
@TypeConverters(FlickrImageConverters::class)
@SerializedName("item")
val items: MutableList<FlickrImage>? = null
)
or
@Entity(tableName = "images")
class DatabaseImagesEntity {
@PrimaryKey(autoGenerate = true)
var id: Int? = 0
@TypeConverters(FlickrImageConverters::class)
@SerializedName("item")
val items: MutableList<FlickrImage>? = null
}
then update your DAO query to @Query("select * from images")
I named it images as an example - you can choose whatever you want.
来源:https://stackoverflow.com/questions/59887192/android-room-typeconverter-issue-while-retriving-list-of-objects