Вставка только уникальных значений в объекте объекта
Есть ли что-то похожее на это: @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