Android Room TypeConverters未被识别

18

我正在尝试实现一个DateConverter以持久化日期。这相当通用,但我一直收到以下错误信息:

无法确定如何将此字段保存到数据库中。您可以考虑为其添加类型转换器。

我仔细检查了在数据库级别和字段级别上定义的注释, 但它仍然无法解析该字段已定义类型转换器的情况。

我的依赖文件:

compile('android.arch.persistence.room:runtime:1.0.0-alpha3') {
    exclude group: 'com.google.code.gson'
}
compile('android.arch.persistence.room:rxjava2:1.0.0-alpha3') {
    exclude group: 'com.google.code.gson'
}
testCompile('android.arch.persistence.room:testing:1.0.0-alpha3') {
    exclude group: 'com.google.code.gson'
}
annotationProcessor('android.arch.persistence.room:compiler:1.0.0-alpha3') {
    exclude group: 'com.google.code.gson'
}

在我的AppDatabase中:

@Database(entities = {Location.class, Room.class, Amenity.class, UserModel.class, EventModel.class}, version =1, exportSchema = false)
@TypeConverters({DateConverter.class})
public abstract class AppDatabase extends RoomDatabase {

    public abstract RoomDao getRoomDao();
    public abstract LocationDao getLocationDao();
    public abstract AmenityDao getAmenityDao();
    public abstract UserDao getUserDao();
    public abstract EventDao getEventDao();

}

那么我的DateConverter类看起来就像这样:

public class DateConverter {

    @TypeConverter
    public static Date toDate(Long timestamp) {
        return timestamp == null ? null : new Date(timestamp);
    }

    @TypeConverter
    public static long toTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}

我的实体长这样:

@Entity(tableName = "event")
@TypeConverters({DateConverter.class})
public class EventModel {

    @PrimaryKey
    private String uuid;

    @ColumnInfo(name = "subject")
    private String subject;

    @TypeConverters({DateConverter.class})
    private Date start;

    @TypeConverters({DateConverter.class})
    private Date end;

    @ColumnInfo(name = "confirmed")
    private Boolean confirmed;

    public String getUuid() {return uuid;}
    public void setUuid(String uuid) {this.uuid = uuid;}

    public String getSubject() {return subject;}
    public void setSubject(String subject) {
        this.subject = subject;
    }

    public Date getStart() {return start;}
    public void setStart(Date date) {this.start = date;}

    public Date getEnd() {return end;}
    public void setEnd (Date end) {
        this.end = end;

    }

    public Boolean getConfirmed() {return confirmed;}

    public void setConfirmed(Boolean confirmed) {
        this.confirmed = confirmed;
    }

}

我还有什么遗漏的吗?谢谢!


1
你确定它的编译是正确的吗?因为一个返回long的方法不应该能够返回null - Kiskae
2
你找出问题了吗?我也遇到了同样的问题,一切看起来都配置得很好,但我仍然遇到了那个问题。 - Franco
1
@user8290985 你解决了这个问题吗?我也遇到了完全相同的问题。 - r.zarei
2个回答

5
尝试更改:
public static long toTimestamp(Date date)

to:

public static Long toTimestamp(Date date)

或者,将另一个参数更改为“long”。也就是说,让它们使用相同的类型。
例如,在此示例项目中,我使用以下类,并且它可以正常工作:
/***
 Copyright (c) 2017 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain    a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS,    WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.

 Covered in detail in the book _Android's Architecture Components_
 https://commonsware.com/AndroidArch
 */

package com.commonsware.android.room;

import android.arch.persistence.room.TypeConverter;
import java.util.Date;

public class TypeTransmogrifier {
  @TypeConverter
  public static Long fromDate(Date date) {
    if (date==null) {
      return(null);
    }

    return(date.getTime());
  }

  @TypeConverter
  public static Date toDate(Long millisSinceEpoch) {
    if (millisSinceEpoch==null) {
      return(null);
    }

    return(new Date(millisSinceEpoch));
  }
}

5
Kotlin 中的等效代码是:(至少我正在使用的这个)
class DateConverter {
    @TypeConverter
    fun toDate(timestamp: Long?): Date? {
        return when (timestamp) {
            null -> null
            else -> Date(timestamp)
        }
    }

    @TypeConverter
    fun toTimestamp(date: Date?): Long? {
        return date?.time
    }
}

接下来你需要准备好你的数据库:

@Database(entities = arrayOf(MyObject::class), version = 1)
@TypeConverters(DateConverter::class)
abstract class MyObjectDb : RoomDatabase() {
    abstract fun myObjectDao(): MyObjectDao
}

11
为什么这是最受欢迎的回答?问题在哪里要求等效的Kotlin代码? - ChumiestBucket
@MartinMarconcini:可能会被踩是因为你的回答并没有解释为什么TypeConverter无法被识别。阅读这个问题的人都有同样的问题,并且已经在使用Kotlin,所以这个答案并没有帮助。 - whatsisname

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接