meldestelle/docs/01_Architecture/Reference/Architektonische-Evolution-Migrationsleitfaden_Exposed-1-0-0-rc-4_zu_1-0-0_01-2026.md
Stefan Mogeritsch 86d8d780f5 docs: update Exposed 1.0.0 migration guide with troubleshooting and fixes
Refined migration steps to address compatibility issues with `JdbcTransaction` and `PreparedStatementApi`. Added detailed troubleshooting for `exec` and `executeUpdate` usage. Updated formatting and clarified best practices for transitioning to Exposed 1.0.0.
2026-02-02 12:37:48 +01:00

6.4 KiB
Raw Blame History

type status owner date
Reference ACTIVE Lead Architect 2026-02-02

Architektonische Evolution Migrationsleitfaden: Exposed 1.0.0-rc-4 → 1.0.0

Dieses Dokument fasst die Auswirkungen und konkreten Migrationsschritte für das Update von JetBrains Exposed von 1.0.0-rc-4 auf die stabile Version 1.0.0 zusammen. Ziel ist eine sichere, reproduzierbare Migration ohne Regressionsrisiken und unter Wahrung unserer Architektur-Governance (API/Domain/Infrastructure-Trennung, zentrale Versionierung über Platform/BOM).

1. Breaking Changes (relevant für uns)

1.1 Überarbeitung der UUID-Unterstützung (Kotlin Multiplatform)

Aufgrund der Einführung der nativen kotlin.uuid.Uuid mussten bestehende Klassen, die auf java.util.UUID basieren, verschoben werden, um Namenskollisionen zu vermeiden.

  • Paket-Migration: Bestehende UUID-Klassen wurden in ein .java-Subpaket verschoben:

  • org.jetbrains.exposed.v1.core.dao.id.UUIDTable -> ...id.java.UUIDTable

  • org.jetbrains.exposed.v1.core.UUIDColumnType -> ...core.java.UUIDColumnType

  • org.jetbrains.exposed.v1.dao.UUIDEntity -> ...dao.java.UUIDEntity

  • Methoden-Änderung: Die Standardmethode Table.uuid() akzeptiert nun ausschließlich kotlin.uuid.Uuid.

  • Migrationspfad: Für die Weiterverwendung von java.util.UUID muss stattdessen die neue Extension-Funktion Table.javaUUID() genutzt werden.

1.2 Refactoring des Transaction Managers

Die Typisierung der Transaction Manager wurde spezifiziert, um besser zwischen JDBC und R2DBC zu unterscheiden.

  • Spezifische Rückgabetypen: Database.transactionManager und R2dbcDatabase.transactionManager geben nun Instanzen von JdbcTransactionManager bzw. R2dbcTransactionManager zurück (statt des generischen TransactionManager).

  • Entfernung von APIs: Die Methode TransactionManagerApi.currentOrNull() wurde entfernt.

  • Ersatz: Nutzen Sie stattdessen die Extension-Funktionen JdbcTransactionManager.currentOrNull() / R2dbcTransactionManager.currentOrNull() oder die statische Methode TransactionManager.currentOrNull().

1.3 R2DBC API Bereinigungen

Um die API näher an die zugrunde liegenden Treiber-Spezifikationen (io.r2dbc.spi) zu bringen, wurden ungenutzte Methoden entfernt.

  • R2dbcPreparedStatementApi: Die Methoden closeIfPossible() und cancel() wurden entfernt, da sie in der R2DBC-Spi keine Entsprechung finden.

  • Methoden-Umbenennung: R2dbcTransaction.closeExecutedStatements() wurde in .clearExecutedStatements() umbenannt. Diese Methode ist nun nicht mehr suspendierbar (non-suspending).

1.4 SQLite & JSONB Automatisierung

Das Handling von JSONB-Spalten in SQLite wurde vereinheitlicht.

  • Automatisches Wrapping: Bei der Verwendung von jsonb() werden Spalten in der SELECT-Klausel nun automatisch in die SQL-Funktion JSON() eingepackt, um die Lesbarkeit zu verbessern.

  • Konfiguration: Dieses Verhalten kann über den Parameter castToJsonFormat=false deaktiviert werden.

  • Core-Interface: Das Interface JsonColumnMarker in exposed-core wurde um die Eigenschaft needsBinaryFormatCast erweitert.

1.5 Sonstige Anpassungen

  • Logging-Level: Die Protokollierung für Transaction-Retry-Verzögerungen und Rollback-Fehler wurde von WARN auf DEBUG herabgestuft.

  • Transaktions-ID: Das Feld Transaction.id wurde endgültig in Transaction.transactionId umbenannt, um Shadowing-Probleme mit Benutzer-Code zu vermeiden.


2. Migrationsschritte (How-To)

  1. Zentralversion heben:
  • gradle/libs.versions.toml: exposed = "1.0.0" setzen.
  • Platform-BOM importieren; keine Direktversionen in Modul-Builds.
  1. UUID-Pfade prüfen:
  • Nutzung von Table.uuid() evaluieren; falls java.util.UUID benötigt, auf Table.javaUUID() wechseln.
  • Etwaige Referenzen auf verschobene .UUID*-Typen auf das neue .java-Subpaket anpassen.
  1. TransactionManager-Aufrufe:
  • Verwendungen von TransactionManagerApi.currentOrNull() entfernen.
  • Stattdessen JdbcTransactionManager.currentOrNull() bzw. TransactionManager.currentOrNull() einsetzen.
  1. R2DBC (falls verwendet):
  • Entfernte Methoden (closeIfPossible, cancel) nicht mehr aufrufen.
  • Umbenennung auf .clearExecutedStatements() berücksichtigen (non-suspending).
  1. JSON/SQLite:
  • Verhalten von jsonb() mit castToJsonFormat prüfen und ggf. deaktivieren.

3. Troubleshooting & Lessons Learned (Update 2026-02-02)

3.1 Low-Level JDBC Zugriff (exec, executeUpdate)

Bei der Migration von DatabaseUtils.kt traten Probleme mit der Auflösung von exec und executeUpdate auf.

  • Problem: Die generische Transaction Klasse bietet in Exposed 1.0.0 keinen direkten Zugriff mehr auf exec mit ResultSet-Verarbeitung oder executeUpdate. Diese Methoden sind nun spezifischer in JdbcTransaction oder PreparedStatementApi verortet.
  • Lösung:
    • Explizite JdbcTransaction: Unsere Transaction-Wrapper (transactionResult) wurden angepasst, um JdbcTransaction als Receiver (this) zu erzwingen.
    • exec mit StatementType: Aufrufe von exec müssen nun den explicitStatementType Parameter (z.B. StatementType.SELECT) nutzen, damit der Compiler die korrekte Überladung wählt.
    • executeUpdate Workaround: Da PreparedStatementApi in Exposed 1.0.0 nicht AutoCloseable ist und executeUpdate teilweise schwer aufzulösen war, nutzen wir try-finally mit closeIfPossible() und greifen bei Bedarf auf die native JDBC Connection zu.
// Beispiel für korrekten Low-Level Zugriff in Exposed 1.0.0
transactionResult(database) {
  // 'this' ist JdbcTransaction
  this.exec("SELECT ...", explicitStatementType = StatementType.SELECT) { rs -> ... }
}

4. Test-Matrix

  • Unit: DSL-Typen (UUID, Zeittypen), Mappings, einfache Inserts/Selects.
  • Integration: JDBC/Hikari Konfiguration, batchInsert, Upsert/Ignore-Pfade.
  • E2E (Docker): CRUD-Flows über den Service hinweg; Metriken/Health.

5. Rollback-Plan

  • git revert des Version-Bumps in libs.versions.toml und ggf. betroffener Anpassungs-Commits.
  • Rebuild; E2E-Smoketest durchführen.
  • Dokumentenstatus auf ARCHIVED setzen oder Nachtrag mit „Rollback erfolgt“ ergänzen.

6. Diagramm (Flow)

flowchart TD
  A[Version Catalog: exposed=1.0.0] --> B[Platform BOM constraints]
  B --> C[Module Build]
  C --> D[Unit/Integration Tests]
  D --> E[Docker E2E]