Skip to content
This repository was archived by the owner on Feb 22, 2026. It is now read-only.

Fix bean definition conflicts in transactional engine#14

Merged
ancongui merged 2 commits into
developfrom
fix/bean-definition-conflicts
Feb 13, 2026
Merged

Fix bean definition conflicts in transactional engine#14
ancongui merged 2 commits into
developfrom
fix/bean-definition-conflicts

Conversation

@casc84ab
Copy link
Copy Markdown
Contributor

Summary

  • ObjectMapper: Removed @Primary from sagaObjectMapper() in SagaPersistenceAutoConfiguration to prevent conflict with eventsourcing's @Primary ObjectMapper when both modules are on the classpath. The @ConditionalOnMissingBean guard remains as fallback.
  • TccEvents: Removed the redundant simple tccEvents() bean that blocked the composite tccEventsComposite() from being created due to @ConditionalOnMissingBean ordering. Removed @ConditionalOnMissingBean(TccEvents.class) from tccEventsComposite() so the composite pattern is always active (consistent with sagaEventsComposite).
  • WebClient.Builder: Added @ConditionalOnMissingBean to webClientBuilder() to avoid conflict with Spring Boot's auto-configured WebClient.Builder.

Test plan

  • Verify transactional engine starts correctly with eventsourcing module on classpath (ObjectMapper conflict resolved)
  • Verify TCC engine initializes with composite TccEvents (logging, micrometer, tracing adapters active)
  • Verify WebClient.Builder does not conflict with Spring Boot's default when WebFlux is on classpath
  • Run existing saga and TCC integration tests to confirm no regressions

- Remove @primary from sagaObjectMapper to prevent conflict with
  eventsourcing's @primary ObjectMapper when both are on classpath
- Remove redundant simple tccEvents bean that prevented the composite
  TccEvents from being created due to @ConditionalOnMissingBean ordering
- Remove @ConditionalOnMissingBean from tccEventsComposite so the
  composite pattern is always active (consistent with sagaEventsComposite)
- Add @ConditionalOnMissingBean to webClientBuilder to avoid conflict
  with Spring Boot's auto-configured WebClient.Builder
@casc84ab casc84ab requested a review from ancongui February 13, 2026 09:55
Copy link
Copy Markdown
Contributor

@ancongui ancongui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: Fix bean definition conflicts in transactional engine

Summary

This PR makes three changes:

  1. Removes @Primary from sagaObjectMapper() to prevent conflict with eventsourcing's @Primary ObjectMapper
  2. Removes the redundant simple tccEvents() bean and removes @ConditionalOnMissingBean(TccEvents.class) from tccEventsComposite()
  3. Adds @ConditionalOnMissingBean to webClientBuilder()

CI Status

BUILD FAILS — 3 test errors in TccEngineIntegrationTest

Findings

1. 🔴 CRITICAL: Build failure — dual @Primary conflict in tests (Severity: Critical)

The build fails with:

No qualifying bean of type 'TccEvents' available: more than one 'primary' bean found 
among candidates: [tccEventsComposite, testEvents]

The root cause: removing @ConditionalOnMissingBean(TccEvents.class) from tccEventsComposite() means it is ALWAYS registered. But TccEngineIntegrationTest likely defines its own testEvents bean (also @Primary), creating a conflict.

Fix options:

  • Option A: Keep @ConditionalOnMissingBean(TccEvents.class) on tccEventsComposite() — but then the test's testEvents bean would shadow the composite, which may not be desired.
  • Option B: Remove @Primary from tccEventsComposite() and use @Qualifier where needed.
  • Option C: Update the test configuration to not use @Primary on its testEvents bean (use @Qualifier instead).

2. ✅ Removing @Primary from sagaObjectMapper() (Severity: None — correct)
This is a good change. The @ConditionalOnMissingBean guard ensures the bean only registers when no other ObjectMapper exists, and removing @Primary prevents conflicts with the eventsourcing module's ObjectMapper. Clean and correct.

3. ✅ Adding @ConditionalOnMissingBean to webClientBuilder() (Severity: None — correct)
This is a good addition. Spring Boot auto-configures a WebClient.Builder when WebFlux is on the classpath, and this guard prevents the conflict. Standard Spring Boot practice.

4. ⚠️ Removing the simple tccEvents() bean (Severity: Medium)
Removing the simple tccEvents() bean that wraps only the LoggingTransactionalObserver is fine IF the composite always being active is the desired behavior. However, this changes behavior for existing consumers who might have relied on the simple bean being the default when micrometer/tracing weren't on the classpath. The composite should still work fine in that case (it uses ObjectProvider for optional observers), but verify this doesn't change the behavior path.

Recommendation

REQUEST CHANGES — The build is failing due to the @Primary conflict in TccEngineIntegrationTest. This must be fixed before merging. The ObjectMapper and WebClient.Builder changes are correct and ready.

Make tccEventsComposite aggregate all TccEvents beans from the
ApplicationContext (consistent with sagaEventsComposite pattern).
This allows test and custom TccEvents beans to be collected by the
composite without requiring @primary, preventing the dual-primary
conflict that caused build failures.
@ancongui ancongui merged commit 64b9a81 into develop Feb 13, 2026
4 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants