Step #5: Creating a Transmogrifier
If you try building the project — for example, Build > “Make module ‘app’” from the Android Studio main menu — you will get build errors, such as:
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it. private final java.time.Instant createdOn = null;
The problem is that Room does not know what to do with an Instant
object. SQLite does not have a native date/time column type, and Room cannot convert arbitrary objects into arbitrary SQLite column types. Instead, Room’s annotation processor detects the issue and fails the build.
To fix this, we need to teach Room how to convert Instant
objects to and from some standard SQLite column type. And for that… we could really use another Kotlin class. Fortunately, you can never have too many Kotlin classes!
(NARRATOR: you definitely can have too many Kotlin classes, but one more will not hurt)
Right-click over the com.commonsware.todo.repo
package in the java/
directory and choose “New” > “Kotlin File/Class” from the context menu. For the name, fill in TypeTransmogrifier
. But, this time, choose “Object” for the kind. Press Enter or Return to create the class, giving you:
package com.commonsware.todo.repo
object TypeTransmogrifier {
}
A transmogrifier is a ~30-year-old piece of advanced technology that can convert one thing into another. Here, we are creating a type transmogrifier: a set of functions that turn one type into another.
To that end, replace the stub generated class with this:
package com.commonsware.todo.repo
import androidx.room.TypeConverter
import java.time.Instant
object TypeTransmogrifier {
@TypeConverter
fun fromInstant(date: Instant?): Long? = date?.toEpochMilli()
@TypeConverter
fun toInstant(millisSinceEpoch: Long?): Instant? = millisSinceEpoch?.let {
Instant.ofEpochMilli(it)
}
}
The @TypeConverter
annotations tell Room that this is a function that can convert one type into another. Here, we convert Instant
objects into Long
objects, using the time-since-the-Unix-epoch methods on Instant
.
Then, add this annotation to the ToDoDatabase
class declaration, under the existing @Database
annotation:
@TypeConverters(TypeTransmogrifier::class)
This tells Room that for any entities used by this ToDoDatabase
, if you need to convert a type, try looking for @TypeConverter
methods on TypeTransmogrifier
.
Now, if you choose Build > “Make module ‘app’” from the Android Studio main menu, the app should build successfully.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.