Вставка только уникальных значений в объекте объекта

Есть ли что-то похожее на это: @Insert(onConflict = OnConflictStrategy.REPLACE), найденный в базе данных Room, который вы можете сделать в Objectbox. Если нет, как вы можете избежать сохранения повторяющихся записей в объекте objectbox? Благодарю.

3 ответа

private Box<User> userBox;
userBox = ObjectBox.get().boxFor(User.class);

//your inserted object 

if (!userBox.getAll().contains(insertedObject)){
                        leadBoxForLeadOpions.put(l);
                    }

Просто используйте@Unique()аннотацию в поле, которое вы хотите сделать уникальным, например:

      @Entity()
class FooEntity {
  @Id()
  int id;//some id

  @Unique()
  int fooField;//unique field
}

По документам objectBox:

      /// Enforces that the value of a property is unique among all objects in a box
/// before an object can be put.
///
/// Trying to put an object with offending values will result in a
/// [UniqueViolationException] (see [ConflictStrategy.fail]).
/// Set [onConflict] to change this strategy.
///
/// Note: Unique properties are based on an [Index], so the same restrictions apply.
/// It is supported to explicitly add the [Index] annotation to configure the
/// index.
class Unique {
  /// The strategy to use when a conflict is detected when an object is put.
  final ConflictStrategy onConflict;

  /// Create a Unique annotation.
  const Unique({this.onConflict = ConflictStrategy.fail});
}

      
/// Used with [Unique] to specify the conflict resolution strategy.
enum ConflictStrategy {
  /// Throws [UniqueViolationException] if any property violates a [Unique] constraint.
  fail,

  /// Any conflicting objects are deleted before the object is inserted.
  replace,
}

По умолчанию у вас будет поведение при сбое, это означает, что если значение вfooFieldуже сохранен, objetbox выдаст ошибку. С другой стороны, если поставитьonConflictсвойство в аннотации кConflictStrategy.replace, объект будет заменен.

Окончательный подход будет таким:

      @Entity()
class FooEntity {
  @Id()
  int id;//some id

  @Unique(onConflict: ConflictStrategy.replace)
  int fooField;
}

Если вы хотите сделать это по идентификатору класса, просто используйтеUniqueиIdна том же поле. Так:

      @Entity()
class FooEntity {
  @Id()
  @Unique(onConflict: ConflictStrategy.replace)
  int id;//some id

  int fooField;
}

Надеюсь, это решит проблему. Это сделало это для моего.

Замена объектов должна быть достаточно простой, как установка @id(assignable=true)аннотация к желаемому полю id. Я протестировал его в своем приложении для Android через:

@Test
fun testAssignableIdsGetReplaced() {
    val myUser1 = User()
    myUser1.id = 1
    myUser1.nickname = "Original"
    var currentList = boxStore!!.boxFor(User::class.java).all
    assert(currentList.size == 0)
    boxStore!!.boxFor(User::class.java).put(myUser1)
    currentList = boxStore!!.boxFor(User::class.java).all
    assert(currentList.size == 1)
    assert(currentList.get(0).id == 1L)
    val newUser1 = User()
    newUser1.id = 1
    newUser1.nickname = "New"
    boxStore!!.boxFor(User::class.java).put(newUser1)
    currentList = boxStore!!.boxFor(User::class.java).all
    assert(currentList.size == 1)
    assert(currentList.get(0).id == 1L)
    assert(currentList.get(0).nickname == newUser1.nickname)
}

@Entity
class User() {
  @Id(assignable = true) var id: Long = 0
  lateinitvar nickname: String
}

Но имейте в виду, что использование назначаемой аннотации идентификаторов может привести к побочным эффектам: https://docs.objectbox.io/relations
https://docs.objectbox.io/advanced/object-ids

Другие вопросы по тегам