房间不能选择一个构造函数,因为多个构造函数是合适的错误

我尝试在我的android kotlin项目中实现持久化库,但在编译时捕获这个错误:

错误:由于多个构造函数合适,房间无法选择构造函数。 尝试用@Ignore注释不需要的构造函数。

错误代码:

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

我有这个错误,因为kotlin显然会生成具有默认参数值的单个kotlin构造函数的多个java构造函数。 工作代码见下:

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

这对我工作:

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

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

Kotlin的数据类使用默认的构造函数生成几个方法。 这意味着equals() , hashCode() , toString() , componentN()函数和copy()是使用分配给构造函数的属性生成的。

使用上述的解决方案

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

生成所有上面列出的方法仅用于id。 使用equals会导致不想要的质量,与toString()相同。 解决这个问题需要你在构造函数中拥有你想要处理的所有属性,并使用ignore来添加第二个构造函数

 @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和复制的方法。 只有这个解决方案是在运行时避免不必要的错误。

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

 @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为true