objectbox / objectbox/objectbox-java

Entities in Backlink ToMany reappearing after removing

オープン
#1,065 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

bug
主要言語
Java
スター
4.6k
フォーク
311
PR マージ指標
30日以内にマージされた PR はありません

説明

Describe the bug
When trying to remove entities from a One-To-Many relationship, they keep reappearing in the database after put() when first removing from the relationship and afterwards from box

Basic info (please complete the following information):

  • ObjectBox version: 3.1.0
  • Reproducibility: always
  • Device: Galaxy S10 (Android 11), OnePlus 6T (Android 11), Pixel 4 (Android 12)
  • OS: Android 11 and 12

To Reproduce
Steps to reproduce the behavior:

  1. Create 2 entities with a 1:N relationship (one and many)
  2. Add some entities to the ToMany (many) of the other (one).
  3. Remove 1 entity from the relationship with one.many.removeById(id)
  4. Remove the entity from the box box.remove(id)
  5. Put the parent (one) in the box again (overriding it)

Expected behavior
No matter the order, if an entity gets deleted from the box and the relation and is nowhere to be found, it should not reappear in the box.

Code
My Repo
Example code where I tested the issue in a Kotlin project

fun main(args: Array<String>) {
    val store: BoxStore = MyObjectBox.builder().name("objectbox-notes-db").build()
    val imageBox = store.boxFor<Image>().also { it.removeAll() }
    val propertyBox = store.boxFor<Property>().also { it.removeAll() }
    val originalImage = Image()
    imageBox.put(originalImage)
    originalImage.apply {
        properties.addAll(listOf(
            Property(name = "h1"),
            Property(name = "h2"),
            Property(name = "h3")
        ))
    }
    imageBox.put(originalImage)
    println("Boxed Properties: " + propertyBox.all.map { it.id })
    println("Original Image Properties: " + originalImage.properties.map { it.id })
    val removedID = propertyBox.all.first().id
    println("Removing id ${removedID}")
    val image = imageBox.get(originalImage.id).also {
        it.properties.removeById(removedID) //changing the order of these 2 will make 
        propertyBox.remove(propertyBox.all.first().id) // it work as expected
        it.properties.applyChangesToDb()
    }
    println("--------------")
    println("Both houldn't have ${removedID}: ")
    println("Boxed Properties before put: " + propertyBox.all.map { it.id })
    println("New Image Properties before put: " + image.properties.map { it.id })

    imageBox.put(image)

    println("--------------")
    println("Should still not have ${removedID}")
    println("Boxed Properties after put: " + propertyBox.all.map { it.id })
    println("New Image Properties after put: " + image.properties.map { it.id })
    }

@Entity
data class Image(
    @Id
    var id: Long = 0,
   ....
) {
    @Backlink(to = "image")
    lateinit var properties: ToMany<Property>
}

@Entity
data class Property(
    @Id
    var id: Long = 0,
   ..
) {
    lateinit var image: ToOne<Image>
}

Additional context
Flipping the order (e.g. first removing the entity from the box) and THEN removing it from the ToMany works.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

Kotlinでの再現と app/src/main/java/com/mobilecomputing/collit/data/datasource/LocalImageDataSource.kt から始め、ToMany.removeById、applyChangesToDb、Box.put に焦点を当てます。削除の両方の順序を再現し、リレーションの更新を追跡します。操作の順序に関係なく、parent を put した後に削除した Property が再び現れなければ完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
android, kotlin
領域
database, mobile
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。