objectbox / objectbox/objectbox-dart

putMany does not enforce @Unique ignores empty/null values

Open
#788 2 comments 0 reactions 1 assignee View on GitHub

@greenrobot-team is already working on this.

Since Feb 18, 2026.

bug
Dominant language
Dart
Stars
1.2k
Forks
162
Avg merge
15m
Merged PRs (30d)
1

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.