Skip to content

GH-1925 - Prevent completed event publications from being resubmitted or marked as failed - #1926

Closed
char-yb wants to merge 17 commits into
spring-projects:mainfrom
char-yb:fix/gh-1925-completed-publication-transitions
Closed

char-yb wants to merge 17 commits into
spring-projects:mainfrom
char-yb:fix/gh-1925-completed-publication-transitions

Conversation

@char-yb

@char-yb char-yb commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Closes #1925.

The status transitions in JpaEventPublicationRepository, JdbcEventPublicationRepositoryV2 and Neo4jEventPublicationRepository now also require the completion date to be unset. This covers the statements behind markFailed(…), markProcessing(…) and markResubmitted(…), so a publication that completes after it has been looked up as failed or stale is neither claimed for resubmission nor flipped back to FAILED. As a side effect, markProcessing(…) no longer moves a completed publication back to PROCESSING either.

The MongoDB repository already has this guard, along with tests for it from GH-1855 (doesNotFailPublicationCompletedAfterStatusLookup() and doesNotResubmitPublicationCompletedAfterFailedLookup()), so I left it untouched. The issue mentions adding a MongoDB regression test, but those tests already cover it.

The JPA, JDBC and Neo4j test suites each get two tests next to the GH-1565 ones:

  • doesNotResubmitCompletedPublication() expects markResubmitted(…) to return false for a completed publication.
  • doesNotMarkCompletedPublicationFailed() expects no FAILED publication after calling markFailed(…) on a completed one.

Without the change, both fail in the UPDATE completion mode on all three stores. The DELETE and ARCHIVE modes pass either way, as the completed publication is no longer in the table. With the change, the JPA and Neo4j suites pass, and the JDBC suite passes on H2, HSQLDB, MySQL, MariaDB, PostgreSQL, Oracle and SQL Server.

odrotbohm and others added 17 commits October 1, 2026 10:16
…eactivate profiles active by default.

Maven only deactivates profiles active by default if any of the explicitly activated profiles is declared in the same pom that declares the one active by default. We now explicitly declare the releaseTrain profile so that the one named "default" is properly disabled.
Store the original domain event in the Namastack outbox and apply the configured mapping when the record is delivered. This keeps selection and routing based on the original event and reports mapping or broker serialization failures as outbox failures.

Original pull request: spring-projectsGH-1897
Signed-off-by: Roland Beisel <info@rolandbeisel.de>
…Type.of(ResolvableType).

FormattableType.of(ResolvableType) used Class#getName(), which renders array types by their JVM binary names (e.g. [B or [Ljava.lang.String;). As the instance is cached under the same key that FormattableType.of(Class) uses, the broken instance also leaked into Class-based lookups, so the result depended on call order. We now use Class#getTypeName() in line with FormattableType.of(Class).

Original pull request: spring-projectsGH-1902
Signed-off-by: cwjohnpark <pierrotcw@gmail.com>
Refactored test cases.
…ation completion.

CompletionRegisteringAdvisor used to decorate all AFTER_COMMIT @TransactionalEventListener methods, no matter whether spring.modulith.events.registry-trigger-annotation excluded them. For an excluded listener no publication is ever registered, so the completion fell back to the payload-based lookup in the repository, which serializes the event and thus failed for events that cannot be serialized.

The decision which event listener methods are considered by the Event Publication Registry is now encapsulated in EventListenerMethodMetadata, used by both the advisor and TransactionalEventListeners.
… without configured staleness.

DefaultEventPublicationRegistry now only marks publications as failed for statuses Staleness.isMonitored(…) reports as monitored, so configuring only the resubmitted timeout no longer fails PUBLISHED and PROCESSING publications. StalenessProperties rejects zero and negative durations and refuses staleness lookups for statuses that cannot become stale.
…ing resubmitted or marked as failed.

The status transitions in the JPA, JDBC and Neo4j event publication repositories only checked that a publication was not already in the target state. A publication that completed after having been looked up as failed or stale could thus still be claimed for resubmission or be flipped back to FAILED, causing the listener to be invoked again for an already processed event.

The statements used by markFailed(…), markProcessing(…) and markResubmitted(…) now also require the completion date to be unset, in line with the MongoDB repository.

Signed-off-by: char-yb <uiurihappy@naver.com>
…n ApplicationModule exposes via module :: **.
…ing resubmitted or marked as failed.

The status transitions in the JPA, JDBC and Neo4j event publication repositories only checked that a publication was not already in the target state. A publication that completed after having been looked up as failed or stale could thus still be claimed for resubmission or be flipped back to FAILED, causing the listener to be invoked again for an already processed event.

The statements used by markFailed(…), markProcessing(…) and markResubmitted(…) now also require the completion date to be unset, in line with the MongoDB repository.

Signed-off-by: char-yb <uiurihappy@naver.com>
…blications.

MongoDbEventPublicationRepository previously archived completed or abandoned publications via an aggregation using $merge, which MongoDB rejects inside transactions (error 263). We now read the affected publications and write them to the archive collection through a single unordered bulk upsert using $setOnInsert, which is transaction-safe and still keeps already existing archive entries.
@odrotbohm odrotbohm closed this Oct 9, 2026
@char-yb
char-yb deleted the fix/gh-1925-completed-publication-transitions branch October 9, 2026 13:28
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.

Completed event publications can be claimed for resubmission and marked as failed again

4 participants