Skip to content

Release 0.40.28 supporting Spring Boot 3.3.* and later

Pre-release
Pre-release

Choose a tag to compare

@jeppec jeppec released this 08 Feb 16:31
· 40 commits to main since this release

What's Changed

Full Changelog: 0.40.27...0.40.28

Highlights

  • Fixed duplicate message consumption across multiple pods in DurableQueues (Bug #19)
  • Fixed deserialization failures blocking all queues when using the Centralized Message Fetcher - messages now go directly to dead letter queue (Issue #24)
  • Complete rewrote all 30 module README files and created 29 new LLM-optimized reference docs
  • Added Result utility class for functional error/success handling and enhanced Either with new methods
  • Added AnnotationBasedInMemoryProjector for annotation-driven in-memory event projections
  • Updated Testcontainers to v2 and bumped 20+ dependency/plugin versions

✨ New Features

Shared

  • Result utility class: Added Result as a specialized Either for error/success semantics with success(), error(), mapSuccess(), mapError(), flatMapSuccess(), flatMapError(), fold(), swap(), and interop via fromEither()/toEither(). Enhanced Either with fold(), flatMap1(), flatMap2(), and toResult() methods.

Event Store

  • AnnotationBasedInMemoryProjector: Added annotation-based in-memory projections using @EventHandler methods on plain POJO classes. Auto-registered via Spring Boot with essentials.eventstore.add-annotation-based-in-memory-projector=true.

Reactive

  • Customizable exception log level in AnnotatedCommandHandler: Added protected getExceptionLogLevel(Exception) method returning Optional<Level> to allow subclasses to control or suppress exception logging.

Foundation

  • markAsDeadLetterMessageDirect() API: Added new method to DurableQueues interface for marking messages as dead letters without deserializing the payload, with full interceptor support in both PostgreSQL and MongoDB implementations.
  • Type-safe MessageMetaData retrieval: Added get() and getOptional() methods with support for common type conversions.

Kotlin

  • Evolver helper methods: Added extractEvents() and extractEventsAsList() to Evolver for type-safe event extraction from AggregateEventStream.

Spring Boot Starters

  • autoFlushAndPublishAfterAppendToStream config: Added configuration property enabling FlushAndPublishPersistedEventsToEventBusRightAfterAppendToStream interceptor for in-transaction event processing.

Types Integrations

  • Avro LongTypeLogicalType: Added LongTypeLogicalType base class for Avro long-based semantic types, with refactored BaseLongTypeConversion support.

🐛 Bug Fixes

  • Fixed duplicate message consumption with multiple pods: CentralizedMessageFetcher.calculateAvailableWorkerSlotsPerQueue() used Math.max(1, ...) which always fetched at least one message even when all workers were busy, causing messages to be reset as "stuck" and consumed by another pod. Changed to Math.max(0, ...) to prevent fetching when no capacity exists. #19
  • Fixed deserialization failure blocking all queues: When a message failed to deserialize, combined with the Centralized Message Fetcher, it blocked all subsequent messages in the queue. Now uses markAsDeadLetterMessageDirect() to move undeserializable messages directly to the dead letter queue without blocking delivery. #24
  • Fixed bi-temporal price adjustment bugs in ProductPrice aggregate: Corrected findTheValidityPeriodOfTheNextPriceAfter() and findTheValidityPeriodOfThePreviousPriceBefore() to properly filter and locate adjacent price periods. Added guard clause to throw AggregateException when adjusting a non-hydrated aggregate.

🔧 Improvements

Foundation

  • OrderedMessage Javadoc overhaul:
    • Added comprehensive documentation explaining single-node vs multi-node ordering guarantees
    • CentralizedMessageFetcher vs TraditionalMessageFetcher behavior, and the SingleGlobalConsumer solution for cluster-wide ordering.
    • Updated Inboxes, Outboxes, and DurableQueues Javadoc accordingly.
  • Improved PostgresqlUtil and MongoUtil Javadoc: Enhanced SQL/NoSQL validation method descriptions with security notices, limitations, and developer guidance.

Event Store / Event Sourced Aggregates

  • EventStreamEvolver documentation: Added extractEvents() and extractEventsAsList() methods and expanded Javadoc with implementation details, examples, and use cases.
  • Extended EventStoreInterceptor: Now extends Interceptor marker interface for consistency.

Reactive

  • Capped default parallelThreads: LocalEventBus default parallelThreads now capped to max 4 for high-CPU systems. Spring Boot starters cap eventBusParallelThreads, commandBusParallelSendAndDontWaitConsumers, and SchedulerProperties.numberOfThreads to max 4.

📚 Documentation Overhaul

This release includes a comprehensive rewrite of the project's entire documentation surface - both the developer-facing README files and a brand-new set of LLM-optimized reference documents.

LLM-Optimized Reference Documentation (new)

Created 29 new /LLM/LLM-*.md files designed for fast comprehension by LLMs and developers alike. These provide concise, structured API references, usage patterns, and architecture overviews for every module:

  • LLM.md - Master index with module overview and architecture principles
  • LLM-components.md - Component module overview and cross-references
  • LLM-types-index.md and LLM-types-integrations.md - Comprehensive semantic types and integrations lookup tables
  • Module-specific docs for all 28 modules: shared, types, immutable, reactive, foundation, foundation-types, foundation-test, postgresql-event-store, eventsourced-aggregates, kotlin-eventsourcing, postgresql-queue, postgresql-document-db, postgresql-distributed-fenced-lock, springdata-mongo-queue, springdata-mongo-distributed-fenced-lock, spring-postgresql-event-store, spring-boot-starter-modules, types-jackson, types-jdbi, types-avro, types-spring-web, types-springdata-jpa, types-springdata-mongo, immutable-jackson, vaadin-ui

README Overhaul (all modules)

Rewrote all 30 module README files with:

  • Consistent Table of Contents structure across all modules
  • LLM context references linking to the corresponding /LLM/LLM-<module>.md file
  • Expanded security sections with SQL/NoSQL injection warnings and mitigation guidance
  • Comprehensive API documentation with usage examples and code samples
  • New README files for previously undocumented modules: spring-boot-starter-admin-ui and vaadin-ui

Additional Documentation

  • Documented AssertJ testing practices for CharSequenceType equality assertions
  • Documented event projection patterns and Version = EventOrder best practice for PostgreSQL DocumentDB and Event Store
  • Documented EventStreamEvolver integration with InMemoryProjector including usage examples
  • Documented OrderedMessage cluster-wide ordering guarantees with single-node vs multi-node behavior
  • Documented SQL/NoSQL validation limitations across all modules
  • Added comprehensive type and component index for LLM reference lookup

📦 Dependency Updates

Libraries

Dependency Previous Updated
reactor-bom 2024.0.11 2024.0.14
postgresql 42.7.8 42.7.9
assertj 3.27.6 3.27.7
log4j-to-slf4j 2.25.2 2.25.3
junit-bom 5.14.0 5.14.2
testcontainers-bom 1.21.3 2.0.3
jdbi3-bom 3.49.5 3.51.0
jackson-bom 2.19.2 2.20.2
mockito-bom 5.20.0 5.21.0
logback 1.5.19 1.5.25
avro 1.12.0 1.12.1
commons-lang3 3.19.0 3.20.0
tomcat-embed 10.1.48 10.1.50

Plugins

Plugin Previous Updated
maven-resources-plugin 3.3.1 3.4.0
maven-jar-plugin 3.4.2 3.5.0
maven-source-plugin 3.3.1 3.4.0
versions-maven-plugin 2.19.1 2.21.0
dependency-check-maven 12.1.8 12.2.0
flatten-maven-plugin 1.7.2 1.7.3
maven-docker-plugin 0.46.0 0.48.0
central-publishing-maven-plugin 0.9.0 0.10.0

Testcontainers v2 Migration

Aligned all modules to Testcontainers version 2 artifact IDs: postgresql → testcontainers-postgresql, junit-jupiter → testcontainers-junit-jupiter, mongodb → testcontainers-mongodb.