Skip to main content
Version: 1.9.x

Database Support

Supported Databases​

Namastack Outbox supports any JPA/JDBC-compatible relational database. The JDBC module includes automatic schema creation for the following databases:

  • ✅ H2 (development)
  • ✅ MySQL / MariaDB
  • ✅ PostgreSQL
  • ✅ SQL Server
  • ✅ Oracle

MongoDB​

MongoDB is supported via the dedicated namastack-outbox-starter-mongodb module. Collections and indexes are created automatically via Spring Data MongoDB on application startup. For manual index management and index definitions, see MongoDB Schema. For module setup and configuration, see Persistence Modules → MongoDB.


Schema Management​

JDBC Module — Automatic Initialization​

The JDBC module creates the outbox schema automatically on application startup. This is enabled by default and requires no additional configuration.

To disable automatic schema creation (recommended for production deployments that use migration tools):

namastack:
outbox:
jdbc:
schema-initialization:
enabled: false

When disabled, you are responsible for creating the schema using your preferred migration tooling before the application starts.

JPA Module — No Automatic Schema Creation​

The JPA module does not support automatic schema creation. Schema management is delegated to Hibernate or your migration tool.

Option 1: Hibernate DDL Auto (Development Only)

spring:
jpa:
hibernate:
ddl-auto: create # or create-drop for test environments

This is convenient for local development but should never be used in production — it may drop and recreate tables on restart.

Option 2: Flyway or Liquibase (Production)

Create the outbox tables as part of your migration scripts. Database-specific SQL schema files are available in the repository: 👉 Schema Files on GitHub

Then configure Hibernate to validate the schema on startup rather than modify it:

spring:
jpa:
hibernate:
ddl-auto: validate

If the schema does not match the expected structure, Spring Boot will fail to start — which is the desired behavior for production deployments.


Migration Strategies​

Flyway​

Add the Flyway migration file to src/main/resources/db/migration/:

-- V1__create_outbox_tables.sql
-- Copy the content from the appropriate schema file for your database

Liquibase​

Add the outbox table definition to your Liquibase changelog. Use the SQL schema files linked above as the source for the sql changeset type, or translate to Liquibase XML/YAML format.


Troubleshooting​

Table 'outbox_record' doesn't exist The schema has not been initialized. Either enable automatic initialization (JDBC module) or apply the migration scripts before starting the application.

Schema-validation: missing table (JPA module) Hibernate's ddl-auto: validate found a mismatch. Ensure your migration scripts match the schema files for the current library version. Check for pending migrations.

Could not obtain lock on outbox partition (PostgreSQL) This is a normal advisory lock contention message logged at DEBUG level when multiple instances compete for the same partition. It is not an error — the second instance will retry on the next poll cycle.

Oracle: ORA-00955: name is already used by an existing object Automatic schema initialization tried to create tables that already exist. Disable automatic initialization and manage the schema manually.


MongoDB Schema​

When using the MongoDB persistence module, collections and indexes can be created automatically by Spring Data MongoDB (spring.data.mongodb.auto-index-creation=true). However, for production environments it is recommended to manage indexes explicitly using a setup script.

Collections & Indexes​

The MongoDB module uses three collections:

CollectionPurpose
outbox_recordsStores outbox records (events/messages)
outbox_instancesTracks application instances
outbox_partition_assignmentsMaps partitions to instances

When using a custom collection prefix (e.g. myapp_), all collection names are prefixed accordingly (e.g. myapp_outbox_records).

outbox_records Indexes​

Index NameFieldsPurpose
status_idx{ status: 1 }Filter records by status
record_key_created_idx{ recordKey: 1, createdAt: 1 }Ordered lookup by record key
partition_status_retry_idx{ partitionNo: 1, status: 1, nextRetryAt: 1 }Partition-scoped polling query
status_retry_idx{ status: 1, nextRetryAt: 1 }Global retry scheduling
record_key_completed_created_idx{ recordKey: 1, completedAt: 1, createdAt: 1 }Completed record cleanup
fifo_pipeline_idx{ partitionNo: 1, recordKey: 1, createdAt: 1 }FIFO aggregation pipeline for ordered processing

outbox_instances Indexes​

Index NameFieldsPurpose
status_idx{ status: 1 }Filter instances by status
lastHeartbeat_idx{ lastHeartbeat: 1 }Stale instance detection
status_heartbeat_idx{ status: 1, lastHeartbeat: 1 }Combined status + heartbeat query

outbox_partition_assignments Indexes​

Index NameFieldsPurpose
instanceId_idx{ instanceId: 1 }Lookup partitions by instance

Manual Setup Script​

A ready-to-use mongosh script is provided in the repository:

👉 mongodb-setup.js on GitHub

Running the Script​

Default collection names:

mongosh mongodb://localhost:27017/mydb schema/mongodb-setup.js

With a custom collection prefix:

mongosh --eval 'var OUTBOX_PREFIX="myapp_"' mongodb://localhost:27017/mydb schema/mongodb-setup.js

This creates myapp_outbox_records, myapp_outbox_instances, and myapp_outbox_partition_assignments.

Disabling Auto-Index Creation​

When using the manual setup script, disable Spring Data MongoDB's automatic index creation:

spring:
data:
mongodb:
auto-index-creation: false
Production Recommendation

For production environments, it is recommended to disable auto-index-creation and manage indexes via the setup script (or your own migration tooling). This gives you full control over when and how indexes are created, avoiding potential performance impacts during application startup.