Skip to main content
Version: 1.0.0

Quickstart

Namastack Outbox for Spring Boot is a robust Spring Boot library for Java and Kotlin projects that implements the Transactional Outbox Pattern for reliable record publishing in distributed systems. Ensures records are never lost through atomic persistence and automatic retry logic with handler-based processing and partition-aware horizontal scaling.

This guide will get you up and running in 5 minutes with minimal configuration.


Add Dependency

dependencies {
implementation("io.namastack:namastack-outbox-starter-jdbc:1.0.0")
}
JDBC vs JPA

We recommend the JDBC starter for quick start as it supports automatic schema creation. For JPA/Hibernate projects, see JPA Setup below.

Enable Scheduling

@SpringBootApplication
@EnableScheduling // Required for automatic outbox processing
class Application

fun main(args: Array<String>) {
runApplication<Application>(*args)
}

Create Handlers

@Component
class OrderHandlers {
// Typed handler - processes specific payload type
@OutboxHandler
fun handleOrder(payload: OrderCreatedEvent) {
eventPublisher.publish(payload)
}

// Generic handler - processes any payload type
@OutboxHandler
fun handleAny(payload: Any, metadata: OutboxRecordMetadata) {
when (payload) {
is OrderCreatedEvent -> eventPublisher.publish(payload)
is PaymentProcessedEvent -> paymentService.process(payload)
else -> logger.warn("Unknown payload type")
}
}
}

Schedule Records Atomically

@Service
class OrderService(
private val outbox: Outbox,
private val orderRepository: OrderRepository
) {
@Transactional
fun createOrder(command: CreateOrderCommand) {
val order = Order.create(command)
orderRepository.save(order)

// Schedule event - saved atomically with the order
outbox.schedule(
payload = OrderCreatedEvent(order.id, order.customerId),
key = "order-${order.id}" // Groups records for ordered processing
)
}
}

Alternative: Using Spring's ApplicationEventPublisher

If you prefer Spring's native event publishing, annotate your events with @OutboxEvent:

@OutboxEvent(
key = "#this.orderId", // SpEL: uses 'orderId' field
context = [
OutboxContextEntry(key = "customerId", value = "#this.customerId"),
OutboxContextEntry(key = "region", value = "#this.region")
]
)
data class OrderCreatedEvent(
val orderId: String,
val customerId: String,
val region: String,
val amount: BigDecimal
)

@Service
class OrderService(
private val orderRepository: OrderRepository,
private val eventPublisher: ApplicationEventPublisher
) {
@Transactional
fun createOrder(command: CreateOrderCommand) {
val order = Order.create(command)
orderRepository.save(order)

// Publish event - automatically saved to outbox atomically
eventPublisher.publishEvent(
OrderCreatedEvent(order.id, order.customerId, order.region, order.amount)
)
}
}

Both approaches work equally well. Choose based on your preference:

  • Explicit outbox.schedule(): More control, clearer intent, supports any payload type
  • @OutboxEvent + ApplicationEventPublisher: More Spring idiomatic for domain events

Configure (Optional)

namastack:
outbox:
poll-interval: 2000
batch-size: 10
retry:
policy: "exponential"
max-retries: 3
exponential:
initial-delay: 1000
max-delay: 60000
multiplier: 2.0

For a complete list of all configuration options, see Configuration Reference.

That's it! Your records are now reliably persisted and processed.


Supported Databases

Any JPA/JDBC-compatible database is supported. Automatic schema creation is available in the JDBC module for:

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

Schema Files for Flyway/Liquibase:

If you manage your database schema manually, you can find the SQL schema files here: 👉 Schema Files on GitHub


JPA Setup

dependencies {
implementation("io.namastack:namastack-outbox-starter-jpa:1.0.0")
}
Schema Management Required

The JPA module does not support automatic schema creation. Choose one of these options:

Option 1: Hibernate DDL Auto (Development only)

spring:
jpa:
hibernate:
ddl-auto: create # or create-drop

Option 2: Flyway/Liquibase (Recommended for Production)

Use the SQL schema files from our repository and configure Hibernate to validate:

spring:
jpa:
hibernate:
ddl-auto: validate

Next Steps