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)