Federico Mariani created CAMEL-24129:
----------------------------------------

             Summary: 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


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)

Reply via email to