2017-06-19 119 views
6

我试图实现我的Android科特林项目持续的库,但赶上这个错误在编译时:间不能接构造,因为多个构造是合适的错误

error: Room cannot pick a constructor since multiple constructors are suitable. Try to annotate unwanted constructors with @Ignore.

错误代码:

@Entity 
data class Site(
     var name: String = "", 
     var url: String = "", 
     @PrimaryKey(autoGenerate = true) var id: Long = 0) 

回答

6

我有这个错误,因为Kotlin显然使用默认参数值为单个Kotlin构造函数生成多个Java构造函数。工作代码见下:

@Entity 
data class Site(
     var name: String, 
     var url: String, 
     @PrimaryKey(autoGenerate = true) var id: Long) 
+0

我们可以为这个数据类创建二级构造吗? –

+0

你可以尝试伊曼纽尔的回答https://stackoverflow.com/a/46526911/3005202 –

2

这为我工作:

@Entity 
data class Site(
    @PrimaryKey(autoGenerate = true) var id: Long = 0), 
    var name: String = "", 
    var url: String = "", 
    @Ignore var ignored: String? = null 
) 
+0

重要的是要注意,虽然这个工程,'忽略'属性不会被添加到数据库,这可能不是什么人谁问题是试图做的。 – Franco

+0

我不知道为什么,但它的工作。你可以解释吗? –

0

在这里你改变你的应用程序的数据库version并重新启动程序agian,它将工作:

@Database(entities = arrayOf(Site::class), version = 123) abstract class YourAppDatabase : RoomDatabase() { 
    abstract fun yourDao(): YourDao 
} 

,你可以也试试这个data class

@Entity 
    data class Site(@PrimaryKey(autoGenerate = true) var id: Long) { 
    @Ignore constructor() : this(0) 
    var name: String = "", 
    var url: String = "", 
} 

和最后一条指令:您的主键id应该是手动递增

希望能为你工作。 :)

测试以显示上述答案无效。

data class TestModel(var id: Int = 0) { 
    constructor() : this(0) 

    var name: String = "defaultname" 
    var testData: String = "defaulttestData" 
} 

val testModel = TestModel(5) 
testModel.name = "test" 

val testModel2 = TestModel(5) 
testModel2.testData = "testdata" 
testModel2.name = "test" 

info { "Test with name set: $testModel" } 
info { "Testdata equals Testdata2 ${testModel.equals(testModel2)}" } 

回报测试与名称设置:TestModel(ID = 5)和TESTDATA等于Testdata2真正

+0

请删除最后一个逗号','和'@PrimaryKey(autoGenerate = true)'这个配置,你总是可以设置'id = 0'。 :) – SpkingR

4

上述解决方案都不是很好的,因为他们的工作,但可能会导致错误。

Kotlin的Data Class使用默认的构造函数生成了几个方法。这意味着equals(),hashCode(), toString(),componentN() functionscopy()是使用您分配给您的构造函数的属性生成的。

使用上面的解决方案,如

@Entity data class Site(@PrimaryKey(autoGenerate = true) var id: Long) { 
    @Ignore constructor() : this(0) 
    var name: String = "" 
    var url: String = "" 
} 

生成所有只为ID上面列出的方法。使用equals会导致不需要的质量,与toString()相同。解决这个需要你有你要在构造函数中进行处理,并添加使用第二个构造函数忽略像

@Entity data class Site(
    @NonNull @PrimaryKey(autoGenerate = true) var id: Long, 
    var name: String = "", 
    var url: String = "") { 
    @Ignore constructor(id = 0, name = ", url = "") : this() 
} 

你真的应该记住,您经常使用的数据类有类似的toString和复制方法的所有属性。只有这种解决方案正在努力避免运行时出现不必要的错误。