Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Data MongoDB tenant uniqueness: enforce it in an index

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

A read-before-insert check cannot guarantee uniqueness under concurrent requests; a compound unique index can.

The race is between the two reads

Two requests for tenant-west both check that invoiceCode INV-47 is unused. Both reads return empty. If the application relies on that check, both inserts can succeed. A unique index over tenantId and invoiceCode makes the database reject the second insert. A global unique index on invoiceCode would reject a legitimate invoice with the same code in another tenant.

Treat index creation as a deployment step

Spring Data MongoDB does not enable automatic index creation by default. An @CompoundIndex annotation documents the mapping, but an existing production collection still needs a reviewed migration that checks duplicate data before creating the index. Build the index ahead of the application change, record the rollout, and test the duplicate-key exception path. Expand-before-use is the same release principle in a relational store.

Assert both dimensions

Insert INV-47 twice in tenant-west and require one rejection. Insert INV-47 in tenant-east and require success. Inspect the actual index specification in the database; a repository mock cannot prove uniqueness. Return a stable conflict response rather than leaking the raw database error. The annotation is a mapping sketch, not evidence the index exists in production.

Implementation sketch

Java
@Document("invoice_reservations")
@CompoundIndex(name = "tenant_invoice_unique",
    def = "{'tenantId': 1, 'invoiceCode': 1}", unique = true)
class InvoiceReservation {
    @Id String id;
    String tenantId;
    String invoiceCode;
}

Cost and verification

Each insert or update maintains the compound index. The extra write cost buys a database-enforced invariant across every application replica.

Common Mistakes

  • Do not rely on existsBy... followed by insert for a uniqueness guarantee.
  • Do not assume the annotation created an index on an existing deployment.
  • Do not omit tenantId from a tenant-scoped unique key.

Read next

Spring Data MongoDB optimistic locking: save the version you read, Spring JWT tenant claims: reject missing or malformed ownership before conversion, Spring database rollout: add a nullable column before changing every writer, Spring Boot Testcontainers and Flyway: let one owner prepare the test schema.

spring
spring-boot
data-transactions
mongodb-tenant-unique-index
Storage details