【问题标题】:Room database: inserted ID is always 0房间数据库:插入的 ID 始终为 0
【发布时间】:2018-11-12 17:06:29
【问题描述】:

我正在尝试创建列表项的 Room 数据库。我在这里遵循示例:https://medium.com/mindorks/room-kotlin-android-architecture-components-71cad5a1bb35

这是我的数据类:

@Entity(tableName = "itemData")
data class ItemData(@PrimaryKey(autoGenerate = true) var id: Long? = null,
                    @ColumnInfo(name = "text") var text: String,
                    @ColumnInfo(name = "checked") var checked: Boolean

)

DAO:

@Dao
interface ItemDataDAO {

    @Insert(onConflict = REPLACE)
    fun insert(itemData: ItemData) : Long
}

数据库:

@Database(entities = arrayOf(ItemData::class), version = 1)
abstract class ItemDatabase() : RoomDatabase() {


    abstract fun itemDataDao(): ItemDataDAO

    companion object {
        private var INSTANCE: ItemDatabase? = null

        fun getInstance(context: Context): ItemDatabase? {
            if (INSTANCE == null) {
                synchronized(ItemDatabase::class) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            ItemDatabase::class.java, "items.db")
                            .build()
                }
            }
            return INSTANCE
        }

        fun destroyInstance() {
            INSTANCE = null
        }
    }
}

工作线程:

class DbWorkerThread(threadName: String) : HandlerThread(threadName) {

    private lateinit var mWorkerHandler: Handler

    override fun onLooperPrepared() {
        super.onLooperPrepared()
        mWorkerHandler = Handler(looper)
    }

    fun postTask(task: Runnable) {
        mWorkerHandler.post(task)
    }
}

这里是调用插入函数的监听器:

editText.setOnEditorActionListener { v, actionId, event ->
    return@setOnEditorActionListener when (actionId) {
        EditorInfo.IME_ACTION_DONE -> {
            createItem(editText)
            true
        }
        else -> false
    }
}

这里是被调用来插入项目的函数:

fun createItem(editText: EditText) {
    var text = editText.text.toString().trim()
    var itemData = ItemData(text = text, checked = false)
    var id : Long? = 0
    val task = Runnable {
        id = mDb?.itemDataDao()?.insert(itemData)
        println("inserted $id")
    }
    mDbWorkerThread.postTask(task)
}

但 ID 始终为 0,因此只能插入一项。任何人都可以看到问题吗?

我还尝试删除id 的默认null 值,但结果相同。

【问题讨论】:

  • 你是在循环插入吗?显示插入的完整代码,而不仅仅是一个 sn-p。
  • 您将 id 分配给不需要的 itemview,因为它将自动生成,删除该代码并尝试。
  • @KaranMer 发生在哪里?这段代码将插入的返回值赋值给id,也就是插入项的ID。
  • 是的,你是对的,你能直接记录mDb?.itemDataDao()?.insert(itemData)返回的内容而不给它分配变量吗?
  • 发生同样的事情,但 1 是每次都不断插入的 id。

标签: android kotlin android-room


【解决方案1】:

以下更改解决了该问题。

而不是像这样调用构造函数

var itemData = ItemData(text = text, checked = false)

我调用了默认构造函数,然后在构造后设置参数。

var itemData = ItemData()
itemData.text = text
itemData.checked = false

这需要 ItemData 实体的以下构造函数:

constructor():this(null,"",false)

【讨论】:

    【解决方案2】:

    您要添加一个自动增量列:

    @Entity(tableName = "item_data")
    public class ItemData extends BaseObservable {
    
        /** Fields */
        @ColumnInfo(name = "item_id")
        @PrimaryKey(autoGenerate = true)
        private int itemId;
    
        ...
    }
    

    【讨论】:

    • 你能解释更多吗?我已经在列上设置了 autoGenerate。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多