I understand that I should check this myself using the unique identifier, but I'll describe it anyway just in case.
Description
When using putMany() with multiple entities that have the same value for a @Unique(onConflict: ConflictStrategy.replace) property, all entities are
inserted as separate rows instead of replacing each other. The ConflictStrategy.replace only resolves conflicts with entities that existed in the
database before the putMany() call, but does not check for conflicts between entities within the same batch.
This is unexpected — I would expect putMany([e1, e2, e3]) with the same unique value to result in only 1 entity (the last one), similar to calling
put(e1), put(e2), put(e3) sequentially.
Expected behavior
putMany with 10 entities sharing the same @Unique(onConflict: ConflictStrategy.replace) value should result in 1 entity in the database (the last
one replaces all previous).
Actual behavior
All 10 entities are inserted with different objId, completely ignoring the unique constraint within the batch.
Reproduction
@Entity()
class TestUniqueEntity {
@Id()
int objId = 0;
@Unique(onConflict: ConflictStrategy.replace)
String uid;
String name;
TestUniqueEntity({required this.uid, required this.name});
}
// Test code:
final box = store.box<TestUniqueEntity>();
box.removeAll();
final entities = List.generate(
10,
(i) => TestUniqueEntity(uid: '', name: 'field_$i'),
);
box.putMany(entities);
print('Count: ${box.count()}'); // Expected: 1, Actual: 10
final all = box.getAll();
for (final e in all) {
print('objId=${e.objId}, uid="${e.uid}", name="${e.name}"');
}
// Prints 10 separate entities, all with uid=""
Output
Count: 10
objId=487, uid="", name="field_0"
objId=488, uid="", name="field_1"
objId=489, uid="", name="field_2"
objId=490, uid="", name="field_3"
objId=491, uid="", name="field_4"
objId=492, uid="", name="field_5"
objId=493, uid="", name="field_6"
objId=494, uid="", name="field_7"
objId=495, uid="", name="field_8"
objId=496, uid="", name="field_9"
Note
Sequential put() calls do enforce the constraint correctly — put(e2) replaces e1 if they share the same unique value. The issue is specific to putMany().
Version
- objectbox: 4.0.3
- Flutter 3.29.0
I understand that I should check this myself using the unique identifier, but I'll describe it anyway just in case.
Description
When using
putMany()with multiple entities that have the same value for a@Unique(onConflict: ConflictStrategy.replace)property, all entities areinserted as separate rows instead of replacing each other. The
ConflictStrategy.replaceonly resolves conflicts with entities that existed in thedatabase before the
putMany()call, but does not check for conflicts between entities within the same batch.This is unexpected — I would expect
putMany([e1, e2, e3])with the same unique value to result in only 1 entity (the last one), similar to callingput(e1),put(e2),put(e3)sequentially.Expected behavior
putManywith 10 entities sharing the same@Unique(onConflict: ConflictStrategy.replace)value should result in 1 entity in the database (the lastone replaces all previous).
Actual behavior
All 10 entities are inserted with different
objId, completely ignoring the unique constraint within the batch.Reproduction