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:
| Collection | Purpose |
|---|---|
outbox_records | Stores outbox records (events/messages) |
outbox_instances | Tracks application instances |
outbox_partition_assignments | Maps 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 Name | Fields | Purpose |
|---|---|---|
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 Name | Fields | Purpose |
|---|---|---|
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 Name | Fields | Purpose |
|---|---|---|
instanceId_idx | { instanceId: 1 } | Lookup partitions by instance |
Manual Setup Script
A ready-to-use mongosh script is provided in the repository:
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
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.