Android Room - error: Cannot figure out how to save this field into database
Android Room - error: Cannot figure out how to save this field into database
详细日志
error: Cannot figure out how to save this field into database. You can
consider adding a type converter for it.
private final java.util.Date mTime = null;
我有一个字段为
的实体
var mStartTime : Date = Date() // java.util.Date
为什么 Room 不能持久化 Date 对象?什么是 Date 的最佳转换器?
Date
正是https://developer.android.com/training/data-storage/room/referencing-data中给出的例子。
For example, if we want to persist instances of Date, we can write the following TypeConverter to store the equivalent Unix timestamp in the database:
public class Converters {
@TypeConverter
public static Date fromTimestamp(Long value) {
return value == null ? null : new Date(value);
}
@TypeConverter
public static Long dateToTimestamp(Date date) {
return date == null ? null : date.getTime();
}
}
The preceding example defines 2 functions, one that converts a Date object to a Long object and another that performs the inverse conversion, from Long to Date. Since Room already knows how to persist Long objects, it can use this converter to persist values of type Date.
Next, you add the @TypeConverters annotation to the AppDatabase class so that Room can use the converter that you've defined for each entity and DAO in that AppDatabase:
AppDatabase.java
@Database(entities = {User.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
旁注:java.util.Date
被认为设计不当(java.util.Calendar
更糟)。如果您有任何重要的日期时间逻辑并且可以摆脱 API 级别 26(桌面上的 Java 8),通常最好使用 java.time
package. And if you can't, see https://github.com/JakeWharton/ThreeTenABP 作为后向端口。
// Java code will not convert to Kotlin very
// well so here is the Kotlin: Converter
// class
public class Converters {
@TypeConverter
fun fromTimestamp( value: Long?) :
java.sql.Date {
return java.sql.Date(value ?: 0)
}
@TypeConverter
fun dateToTimestamp(date :java.sql.Date?)
:Long {
return date?.getTime() ?: 0
}
// Here is the type converters example in
// Kotlin
@Database(entities = [DbNasaPictures::class],
version = 2)
@TypeConverters(Converters::class)
abstract class PicturesDatabase:
RoomDatabase() {
以上所有答案都是针对以下 strings.But 的列表,可帮助您找到对象列表的转换器。
就在“YourClassName”的位置,添加您的对象 class.
@TypeConverter
public String fromValuesToList(ArrayList<**YourClassName**> value) {
if (value== null) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<**YourClassName**>>() {}.getType();
return gson.toJson(value, type);
}
@TypeConverter
public ArrayList<**YourClassName**> toOptionValuesList(String value) {
if (value== null) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken<List<**YourClassName**>>() {
}.getType();
return gson.fromJson(value, type);
}
在Kotlin中,需要在两个文件中添加@TypeConverters
- 数据库 class 其中扩展了 RoomDatabase
@Database(entities = [ToDo::class], version = 1, exportSchema = false)
@TypeConverters(DateConverter::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun todoDao(): ToDoDao
companion object {
@Volatile private var instance: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase =
instance ?: synchronized(this) { instance ?: buildDatabase(context).also { instance = it } }
private fun buildDatabase(appContext: Context) =
Room.databaseBuilder(appContext, AppDatabase::class.java, "todo")
.fallbackToDestructiveMigration()
.build()
}
}
- 数据class其中@Entity声明需要添加DateConverter class for Date
@Entity(tableName = "todo")
data class ToDo(
@PrimaryKey
val id: Int,
val title: String,
val description: String,
val time: String,
val date: String,
val types: Int,
@TypeConverters(DateConverter::class)
val date_time: Date,
val created: String
)
日期转换器class
import androidx.room.TypeConverter
import java.util.*
class DateConverter {
@TypeConverter
fun toDate(timestamp: Long): Date {
return Date(timestamp)
}
@TypeConverter
fun toTimestamp(date: Date): Long {
return date.time
}
}
详细日志
error: Cannot figure out how to save this field into database. You can
consider adding a type converter for it.
private final java.util.Date mTime = null;
我有一个字段为
的实体var mStartTime : Date = Date() // java.util.Date
为什么 Room 不能持久化 Date 对象?什么是 Date 的最佳转换器?
Date
正是https://developer.android.com/training/data-storage/room/referencing-data中给出的例子。
For example, if we want to persist instances of Date, we can write the following TypeConverter to store the equivalent Unix timestamp in the database:
public class Converters { @TypeConverter public static Date fromTimestamp(Long value) { return value == null ? null : new Date(value); } @TypeConverter public static Long dateToTimestamp(Date date) { return date == null ? null : date.getTime(); } }
The preceding example defines 2 functions, one that converts a Date object to a Long object and another that performs the inverse conversion, from Long to Date. Since Room already knows how to persist Long objects, it can use this converter to persist values of type Date.
Next, you add the @TypeConverters annotation to the AppDatabase class so that Room can use the converter that you've defined for each entity and DAO in that AppDatabase:
AppDatabase.java
@Database(entities = {User.class}, version = 1) @TypeConverters({Converters.class}) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
旁注:java.util.Date
被认为设计不当(java.util.Calendar
更糟)。如果您有任何重要的日期时间逻辑并且可以摆脱 API 级别 26(桌面上的 Java 8),通常最好使用 java.time
package. And if you can't, see https://github.com/JakeWharton/ThreeTenABP 作为后向端口。
// Java code will not convert to Kotlin very
// well so here is the Kotlin: Converter
// class
public class Converters {
@TypeConverter
fun fromTimestamp( value: Long?) :
java.sql.Date {
return java.sql.Date(value ?: 0)
}
@TypeConverter
fun dateToTimestamp(date :java.sql.Date?)
:Long {
return date?.getTime() ?: 0
}
// Here is the type converters example in
// Kotlin
@Database(entities = [DbNasaPictures::class],
version = 2)
@TypeConverters(Converters::class)
abstract class PicturesDatabase:
RoomDatabase() {
以上所有答案都是针对以下 strings.But 的列表,可帮助您找到对象列表的转换器。
就在“YourClassName”的位置,添加您的对象 class.
@TypeConverter
public String fromValuesToList(ArrayList<**YourClassName**> value) {
if (value== null) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<**YourClassName**>>() {}.getType();
return gson.toJson(value, type);
}
@TypeConverter
public ArrayList<**YourClassName**> toOptionValuesList(String value) {
if (value== null) {
return (null);
}
Gson gson = new Gson();
Type type = new TypeToken<List<**YourClassName**>>() {
}.getType();
return gson.fromJson(value, type);
}
在Kotlin中,需要在两个文件中添加@TypeConverters
- 数据库 class 其中扩展了 RoomDatabase
@Database(entities = [ToDo::class], version = 1, exportSchema = false) @TypeConverters(DateConverter::class) abstract class AppDatabase : RoomDatabase() { abstract fun todoDao(): ToDoDao companion object { @Volatile private var instance: AppDatabase? = null fun getDatabase(context: Context): AppDatabase = instance ?: synchronized(this) { instance ?: buildDatabase(context).also { instance = it } } private fun buildDatabase(appContext: Context) = Room.databaseBuilder(appContext, AppDatabase::class.java, "todo") .fallbackToDestructiveMigration() .build() } }
- 数据class其中@Entity声明需要添加DateConverter class for Date
@Entity(tableName = "todo") data class ToDo( @PrimaryKey val id: Int, val title: String, val description: String, val time: String, val date: String, val types: Int, @TypeConverters(DateConverter::class) val date_time: Date, val created: String )
日期转换器class
import androidx.room.TypeConverter import java.util.* class DateConverter { @TypeConverter fun toDate(timestamp: Long): Date { return Date(timestamp) } @TypeConverter fun toTimestamp(date: Date): Long { return date.time } }