2017-06-19 112 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和複製方法的所有屬性。只有這種解決方案正在努力避免運行時出現不必要的錯誤。