You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2026/07/16 11:35:00 UTC
[jira] [Assigned] (CAMEL-24129) camel-jpa: JpaConsumer ignores the configured preDeleteHandler and re-derives it via reflection on every message
[ https://issues.apache.org/jira/browse/CAMEL-24129?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Claus Ibsen reassigned CAMEL-24129:
-----------------------------------
Assignee: Claus Ibsen
> camel-jpa: JpaConsumer ignores the configured preDeleteHandler and re-derives it via reflection on every message
> ----------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24129
> URL: https://issues.apache.org/jira/browse/CAMEL-24129
> Project: Camel
> Issue Type: Bug
> Components: camel-jpa
> Reporter: Federico Mariani
> Assignee: Claus Ibsen
> Priority: Major
>
> h3. Problem
> {{JpaConsumer.processBatch()}} (JpaConsumer.java:199) calls:
> {code:java}
> createPreDeleteHandler().deleteObject(batchEntityManager, result, exchange);
> {code}
> instead of the cached accessor {{getPreDeleteHandler()}} (JpaConsumer.java:259-264), which lazily creates and *caches* the handler:
> {code:java}
> public DeleteHandler<Object> getPreDeleteHandler() {
> if (preDeleteHandler == null) {
> preDeleteHandler = createPreDeleteHandler();
> }
> return preDeleteHandler;
> }
> {code}
> The {{@Consumed}} counterpart a few lines below (line 215) does it correctly via {{getDeleteHandler()}}.
> h3. Impact
> # A user-supplied {{preDeleteHandler}} (the {{@UriParam(label = "consumer")}} option wired in {{JpaEndpoint.createConsumer()}}, JpaEndpoint.java:97-98/160) is *never invoked* -- {{createPreDeleteHandler()}} always re-derives the handler from the {{@PreConsumed}} annotation scan on the entity class (or falls back to the no-op default), completely bypassing anything set via {{setPreDeleteHandler}} / the {{preDeleteHandler}} URI option.
> # {{createPreDeleteHandler()}} runs {{AnnotationHelper.findMethodsWithAnnotation(entityType, PreConsumed.class)}} -- a reflective scan of the entity's methods -- for *every entity of every poll batch*, instead of once per consumer lifetime.
> h3. How to reproduce
> Configure a route with a custom {{preDeleteHandler}}:
> {code:java}
> JpaEndpoint endpoint = ...;
> endpoint.setPreDeleteHandler((em, entityBean, exchange) -> called.set(true));
> {code}
> and observe that {{called}} is never set to {{true}} even though the row is consumed normally, because {{processBatch}} never calls {{getPreDeleteHandler()}}.
> h3. Suggested fix
> Change line 199 to call {{getPreDeleteHandler()}} instead of {{createPreDeleteHandler()}}, mirroring the {{@Consumed}}/{{getDeleteHandler()}} pattern already used a few lines below.
> Found during a broader camel-jpa code review (July 2026).
> _Claude Code on behalf of Croway_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)