quarkusio/quarkus · error · UnsupportedOperationException
Calling a method annotated with @Transactional from a method
Error message
Calling a method annotated with @Transactional from a method annotated with @WithTransaction is not supported. Use either @Transactional or @WithSessionOnDemand/@WithSession/@WithTransaction, but not both, throughout your whole application.
What it means
Same family as above: the @Transactional interceptor detects a WITH_TRANSACTION_METHOD_KEY flag left by a legacy @WithTransaction method up the call stack. Mixing legacy Panache @WithTransaction with @Transactional in one call chain is unsupported and throws UnsupportedOperationException.
Source
Thrown at extensions/reactive-transactions/runtime/src/main/java/io/quarkus/reactive/transaction/runtime/TransactionalInterceptorBase.java:279
public static boolean reactiveInterceptorShouldRun() {
boolean condition = Context.isOnEventLoopThread();
LOG.tracef("Transactional interceptor should run: %s", condition);
return condition;
}
protected void validateLegacyPanacheAnnotations() {
// We are running on the retrieved context, however, the method also switch the safety flag.
Context ignored = vertxContext();
if (ContextLocals.get(SESSION_ON_DEMAND_KEY).isPresent()) {
throw new UnsupportedOperationException(
"Calling a method annotated with @Transactional from a method annotated with @WithSessionOnDemand is not supported. "
+ "Use either @Transactional or @WithSessionOnDemand/@WithSession/@WithTransaction, "
+ "but not both, throughout your whole application.");
}
if (ContextLocals.get(WITH_TRANSACTION_METHOD_KEY).isPresent()) {
throw new UnsupportedOperationException(
"Calling a method annotated with @Transactional from a method annotated with @WithTransaction is not supported. "
+ "Use either @Transactional or @WithSessionOnDemand/@WithSession/@WithTransaction, "
+ "but not both, throughout your whole application.");
}
if (ContextLocals.get(REACTIVE_TRANSACTIONAL_METHOD_KEY).isPresent()) {
throw new UnsupportedOperationException(
"Calling a method annotated with @Transactional from a method annotated with @ReactiveTransactional is not supported. "
+ "Use either @Transactional or @WithSessionOnDemand/@WithSession/@WithTransaction, "
+ "but not both, throughout your whole application.");
}
}
/**
*
* @return the current vertx duplicated context
* @throws IllegalStateException If no vertx context is found or is not a safe context as mandated by the
* {@link VertxContextSafetyToggle}View on GitHub (pinned to e1c734241f)
Solutions
- Replace @WithTransaction with @ReactiveTransactional (or plain @Transactional) on the caller.
- Ensure only one transactional annotation family is used across the whole application per the error message.
- Audit call graphs so legacy Panache annotations never wrap @Transactional methods.
Example fix
// before
@WithTransaction
public Uni<Order> save(Order o) { return repo.persist(o); }
// after
@ReactiveTransactional
public Uni<Order> save(Order o) { return repo.persist(o); } Defensive patterns
Strategy: validation
Validate before calling
void check(Class<?> bean) {
for (Method m : bean.getDeclaredMethods())
if (m.isAnnotationPresent(WithTransaction.class) && usesTransactionalServices(bean, m))
throw new IllegalStateException("@WithTransaction wrapping @Transactional: " + m);
} Try / catch
try {
return service.save(order);
} catch (UnsupportedOperationException e) {
log.error("Replace legacy @WithTransaction with @ReactiveTransactional: {}", e.getMessage());
throw e;
} Prevention
- Replace @WithTransaction with @ReactiveTransactional during migration
- Keep a single transactional annotation family codebase-wide
- Enforce with ArchUnit/annotation scanning in CI
- Document the chosen style in the team wiki
When it happens
Trigger: Calling a @Transactional-annotated method from a method annotated with Panache's @WithTransaction.
Common situations: Incremental migration from @WithTransaction to @Transactional; utility methods still using @WithTransaction while services migrated to @Transactional.
Related errors
- Calling a method annotated with @Transactional from a method
- Calling a method annotated with @Transactional from a method
- Unable to load repository/entity class mapping ->
- Your repository class was not properly detected and assigne
- Entity '%s' was not found. Did you forget to annotate your P
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c750200b2d4fe899.
Report an issue: GitHub.