How to fix TypeConverter class in Android Room (Kotlin)
Asked Answered
L

0

6

I'm using Android Room and I have a problem with it. I made a TypeConverter class (in my case it's ConverterHelper), added annotations @ProvidedTypeConverter, @TypeConverter, and @TypeConverters(ConverterHelper::class) but I get the following error:

java.lang.IllegalArgumentException: Unexpected type converter class com.example.mas_implementation_kotlin.helper.ConverterHelper. Annotate TypeConverter class with @ProvidedTypeConverter annotation or remove this converter from the builder.

Here is my ConverterHelper:

@ProvidedTypeConverter
class ConverterHelper {

   @TypeConverter
   fun stringToListOfStrings(value: String): ArrayList<String> {
       val listType: Type = object : TypeToken<ArrayList<String?>?>() {}.type
       return Gson().fromJson(value, listType)
   }

   @TypeConverter
   fun listOfStringsToString(list: List<String>): String {
       val gson = Gson()
       return gson.toJson(list)
   }

   @TypeConverter
   fun listOfVisitsToString(listOfVisits: List<Visit>): String {
       return Gson().toJson(listOfVisits).toString()
   }

   @TypeConverter
   fun stringToListOfVisits(value: String): List<Visit> {
       val listOfVisits = object : TypeToken<ArrayList<Visit>>() {}.type
       return Gson().fromJson(value, listOfVisits)
   }  
}

Database:

@Database(
   entities = [
       Consultant::class,
       Doctor::class,
       Person::class,
       Place::class,
       PreparationToTest::class,
       Receptionist::class,
       Referral::class,
       Survey::class,
       Technician::class,
       Test::class,
       TestResult::class,
       Visit::class
   ], version = 1
)  
@TypeConverters(ConverterHelper::class)
abstract class AppDatabase : RoomDatabase() {
   public abstract fun entitiesDao(): EntitiesDao
}

My Entity:

@Entity
@TypeConverters
data class Visit(
   @PrimaryKey val id: String,
   @ColumnInfo(name = "visitDate") val visitDate: String,
   @ColumnInfo(name = "visitPlaceId") val visitPlaceId: String,
   @ColumnInfo(name = "defrayalOfExpenses") val defrayalOfExpenses: String,
   @ColumnInfo(name = "additionalInfo") val additionalInfo: String,
   @ColumnInfo(name = "personId") val personId: String,
   @ColumnInfo(name = "consultantId") val consultantId: String,
   @ColumnInfo(name = "receptionistId") val receptionistId: String,
   @ColumnInfo(name = "referralId") val referralId: String,
   @ColumnInfo(name = "visitsStatus") val visitStatus: String,
   @ColumnInfo(name = "testId") val testId: String
)

And this is how i create Db in onCreate method:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(binding.root)
    setUI()
    database = Room.databaseBuilder(
        this,
        AppDatabase::class.java,
        "database"
    )
        .addTypeConverter(ConverterHelper::class)
        .fallbackToDestructiveMigration()
        .build()
    fetchDataFromDatabase()
    fetchListOfBookedVisitsFromDb()
}

This is how i fetched data from db:

private fun fetchDataFromDatabase() {
    val visitAdapter = VisitAdapter(baseContext, this::onClickAction)
    lifecycleScope.launch(Dispatchers.IO) {
        val entitiesDao = database.entitiesDao()
        databaseHelper = DatabaseHelper(entitiesDao)
        visitAdapter.setAdapterList(databaseHelper.getPersonVisitModelList())
        withContext(Dispatchers.Main) {
            binding.mainNewVisitListRecyclerView.apply {
                adapter = visitAdapter
                layoutManager = LinearLayoutManager(this@MainActivity)
            }
        }
    }
}

Where my DatabaseHelper class has method:

fun getPersonVisitModelList(): List<VisitModel> {
    val visitModelList = mutableListOf<VisitModel>()
    val personVisitsString = entitiesDao.getAllPatientVisits()
    val converterHelper = ConverterHelper()
    val personVisitsList = converterHelper.stringToListOfVisits(personVisitsString)
    for (visit in personVisitsList) {
        visitModelList.add(
            VisitModel(
                visit.id,
                getTestTypeByTestId(visit.testId),
                getTestPlaceByPlaceId(visit.visitPlaceId),
                visit.visitDate
            )
        )
    }
    return visitModelList
}

Do you know how to fix this error? I tried commenting getPersonVisitModelList method because I'm not sure if I can create and use an instance of the ConverterHelper class, but the error still occurs.

Llywellyn answered 13/6, 2021 at 10:53 Comment(4)
Remove the @ProvidedTypeConverter annotation. You do not need it.Jive
It's not a fix for the problem. Also, even the exception contains information that the TypeConverter class should be annotated with this annotation, so why it is not needed?Llywellyn
Sorry: remove the @ProvidedTypeConverter annotation and remove addTypeConverter(ConverterHelper::class). All that you need is your existing @TypeConverters(ConverterHelper::class) annotation to apply it to your database.Jive
But if constructor of converter class has parameters than you have to add it through @ProvidedTypeConverter + .addTypeConverter(...) and still you get the runtime error. With @TypeConverters(...) annotation or without itNashua

© 2022 - 2024 — McMap. All rights reserved.