Skip to content

feat: migrate OutboxStore from Exposed to plain JDBC (KOJAK-64)#26

Open
endrju19 wants to merge 6 commits intomainfrom
feat/jdbc-outbox-store
Open

feat: migrate OutboxStore from Exposed to plain JDBC (KOJAK-64)#26
endrju19 wants to merge 6 commits intomainfrom
feat/jdbc-outbox-store

Conversation

@endrju19
Copy link
Copy Markdown
Collaborator

Summary

  • Replaces Exposed ORM in PostgresOutboxStore and MysqlOutboxStore with plain JDBC via new ConnectionProvider fun interface
  • Adds SpringConnectionProvider (uses DataSourceUtils.getConnection()) for seamless Spring integration with any PlatformTransactionManager (JPA, JDBC, jOOQ, MyBatis)
  • Removes OutboxTable Exposed table definitions from both postgres and mysql modules
  • Removes Exposed dependencies from okapi-postgres, okapi-mysql, and okapi-spring-boot

Motivation

Exposed as an internal implementation detail of OutboxStore forced consumers to:

  1. Add 5+ Exposed runtime dependencies (compileOnly in okapi leaked at runtime)
  2. Use Exposed's SpringTransactionManager instead of standard Spring TMs
  3. Create hacks like JpaFlushingTransactionManager for JPA coexistence

With ConnectionProvider, okapi borrows the JDBC connection from whatever transaction mechanism the app uses — zero coupling.

Key changes

Module Change
okapi-core New ConnectionProvider fun interface
okapi-postgres PostgresOutboxStore(connectionProvider, clock) — pure JDBC
okapi-mysql MysqlOutboxStore(connectionProvider, clock) — pure JDBC
okapi-spring-boot SpringConnectionProvider(dataSource) auto-configured
okapi-spring-boot OutboxPurger now takes optional TransactionRunner
okapi-integration-tests JdbcConnectionProvider test helper, updated all tests

Validated by

5 standalone example apps (JPA, JDBC, multi-datasource, jOOQ, Ktor+Exposed) — all passing JUnit tests and smoke tests against this branch.

Test plan

  • All existing integration tests pass (./gradlew test)
  • Concurrency tests pass (PostgreSQL + MySQL)
  • E2E tests pass (HTTP + Kafka delivery)
  • CI green

Replace Exposed ORM with plain JDBC in PostgresOutboxStore and
MysqlOutboxStore. This eliminates the coupling to Exposed's transaction
mechanism, allowing okapi to work transparently with any Spring
PlatformTransactionManager — JPA/Hibernate, JDBC, jOOQ, MyBatis, etc.

Key changes:
- Add ConnectionProvider interface to okapi-core
- Add SpringConnectionProvider using DataSourceUtils.getConnection()
- Rewrite PostgresOutboxStore and MysqlOutboxStore to plain JDBC
- Remove Exposed dependencies from okapi-postgres and okapi-mysql
- Delete OutboxTable.kt from both modules
- Add TransactionRunner to OutboxPurger (fixes connection leak)
- Fix null parameter handling (setNull instead of setTimestamp(null))
- Parameterize status in removeDeliveredBefore SQL
- Change spring-jdbc from compileOnly to implementation
Move ExposedTransactionContextValidator out of okapi-core into a
dedicated okapi-exposed module. Add ExposedConnectionProvider and
ExposedTransactionRunner for Ktor/standalone Exposed apps.

okapi-core is now free of Exposed dependencies — only plain JDK types.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant