-
Notifications
You must be signed in to change notification settings - Fork 150
Description
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