This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit ab959a5b0cb6e63b9b8534f4808c7583309a5e94
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Oct 24 19:57:01 2026 +0200

    CAMEL-24961: Catalog body types for jpa, sql-stored, mybatis, jooq, 
pgevent, duckdb, clickhouse and four more database components (#28393)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/catalog/components/clickhouse.json       |  4 +++
 .../org/apache/camel/catalog/components/drill.json |  4 +++
 .../apache/camel/catalog/components/duckdb.json    |  4 +++
 .../org/apache/camel/catalog/components/jooq.json  |  5 +++
 .../org/apache/camel/catalog/components/jpa.json   |  5 +++
 .../org/apache/camel/catalog/components/kudu.json  |  4 +++
 .../camel/catalog/components/mybatis-bean.json     |  4 +++
 .../apache/camel/catalog/components/mybatis.json   |  5 +++
 .../catalog/components/pg-replication-slot.json    |  3 ++
 .../apache/camel/catalog/components/pgevent.json   |  5 +++
 .../camel/catalog/components/sql-stored.json       |  4 +++
 .../apache/camel/catalog/docs/jooq-component.adoc  |  6 ++--
 .../camel/catalog/docs/mybatis-bean-component.adoc | 12 ++++---
 .../camel/catalog/docs/mybatis-component.adoc      |  5 +--
 .../camel/component/clickhouse/clickhouse.json     |  4 +++
 .../component/clickhouse/ClickHouseEndpoint.java   | 25 +++++++++++++
 .../org/apache/camel/component/drill/drill.json    |  4 +++
 .../camel/component/drill/DrillEndpoint.java       | 12 +++++++
 .../org/apache/camel/component/duckdb/duckdb.json  |  4 +++
 .../camel/component/duckdb/DuckDbEndpoint.java     | 27 ++++++++++++++
 .../org/apache/camel/component/jooq/jooq.json      |  5 +++
 .../camel-jooq/src/main/docs/jooq-component.adoc   |  6 ++--
 .../apache/camel/component/jooq/JooqEndpoint.java  | 17 +++++++++
 .../org/apache/camel/component/jpa/jpa.json        |  5 +++
 .../apache/camel/component/jpa/JpaEndpoint.java    | 30 ++++++++++++++++
 .../org/apache/camel/component/kudu/kudu.json      |  4 +++
 .../apache/camel/component/kudu/KuduEndpoint.java  | 21 +++++++++++
 .../camel/component/mybatis/mybatis-bean.json      |  4 +++
 .../apache/camel/component/mybatis/mybatis.json    |  5 +++
 .../src/main/docs/mybatis-bean-component.adoc      | 12 ++++---
 .../src/main/docs/mybatis-component.adoc           |  5 +--
 .../component/mybatis/MyBatisBeanEndpoint.java     | 13 +++++++
 .../camel/component/mybatis/MyBatisEndpoint.java   | 41 ++++++++++++++++++++++
 .../pg/replication/slot/pg-replication-slot.json   |  3 ++
 .../slot/PgReplicationSlotEndpoint.java            |  8 +++++
 .../apache/camel/component/pgevent/pgevent.json    |  5 +++
 .../camel/component/pgevent/PgEventEndpoint.java   | 12 +++++++
 .../camel/component/sql/stored/sql-stored.json     |  4 +++
 .../component/sql/stored/SqlStoredEndpoint.java    | 25 +++++++++++++
 39 files changed, 351 insertions(+), 20 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json
index 6e4f34d47ff7..db94b15eabb7 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json
@@ -42,6 +42,10 @@
     "CamelClickHouseReadRows": { "index": 5, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "long", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The number of rows read by a query operation.", 
"constantName": 
"org.apache.camel.component.clickhouse.ClickHouseConstants#READ_ROWS" },
     "CamelClickHousePingOk": { "index": 6, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The boolean result of a ping operation.", 
"constantName": 
"org.apache.camel.component.clickhouse.ClickHouseConstants#PING_OK" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "list" ], 
"byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "text", 
"bytes", "stream", "file" ] }, { "option": "operation", "value": "PING", 
"carriers": [ "any" ] } ], "description": "The rows to insert, in the format 
option (JSONEachRow: one JSON object per line), as text, bytes, a stream or a 
file; or a List of objects whose class is registered on the Client. A Map or a 
List of Maps fails: marshal [...]
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "QUERY", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "operation", "value": "PING", "carriers": [ 
"value" ], "javaType": "java.lang.Boolean" } ], "description": "Insert leaves 
the body unchanged, with the count in the CamelClickHouseWrittenRows header. 
Query gives the result as a String in the format option (JSONEachRow: one JSON 
object per line); binary formats such [...]
+  },
   "properties": {
     "database": { "index": 0, "kind": "path", "displayName": "Database", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The ClickHouse database. A 
table may also be provided using the database.table syntax." },
     "asyncInsert": { "index": 1, "kind": "parameter", "displayName": "Async 
Insert", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to use 
ClickHouse server-side asynchronous inserts (async_insert=1)." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json
index e3543bc15f93..c01654c60035 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json
@@ -30,6 +30,10 @@
   "headers": {
     "CamelDrillQuery": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The drill query", "constantName": 
"org.apache.camel.component.drill.DrillConstants#DRILL_QUERY" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the query comes from the CamelDrillQuery header, and a query in the body 
without that header fails" },
+    "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<java.util.Map<String, Object>>", "description": "The rows of 
the query: a List of Maps of the column names (case insensitive) and their 
values, an empty List for no rows. A statement such as CREATE TABLE AS, DROP or 
ALTER SESSION gives the one row Drill answers with, such as ok and summary" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Host name or IP address" },
     "clusterId": { "index": 1, "kind": "parameter", "displayName": "Cluster 
Id", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Cluster ID 
https:\/\/drill.apache.org\/docs\/using-the-jdbc-driver\/#determining-the-cluster-id"
 },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json
index ae7b10fe972c..b018b667caae 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json
@@ -39,6 +39,10 @@
     "CamelDuckDbRowsRead": { "index": 5, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "long", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The number of rows returned by a query.", 
"constantName": "org.apache.camel.component.duckdb.DuckDbConstants#ROWS_READ" },
     "CamelDuckDbPingOk": { "index": 6, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The boolean result of a ping operation.", 
"constantName": "org.apache.camel.component.duckdb.DuckDbConstants#PING_OK" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "query" ], "byOption": [ { "option": "operation", "value": 
"INSERT", "carriers": [ "list" ] }, { "option": "operation", "value": "COPY", 
"carriers": [ "file", "text" ] }, { "option": "operation", "value": "PING", 
"carriers": [ "any" ] } ], "description": "The SQL statement as text, or bytes, 
a stream or a file of it; the query option or the CamelDuckDbQuery header takes 
its place. Insert takes a List of [...]
+    "producerOut": { "carriers": [ "value" ], "javaType": "java.lang.Long", 
"byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "list" 
], "javaType": "java.util.List<java.util.Map<String, Object>>" }, { "option": 
"operation", "value": "PING", "carriers": [ "value" ], "javaType": 
"java.lang.Boolean" }, { "option": "resultFormat", "value": "JSON", "carriers": 
[ "text", "value" ] } ], "description": "The count of rows written or affected 
as a Long, also in the CamelDuckDb [...]
+  },
   "properties": {
     "databasePath": { "index": 0, "kind": "path", "displayName": "Database 
Path", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Database path, either :memory: or a relative 
or absolute file path." },
     "batchSize": { "index": 1, "kind": "parameter", "displayName": "Batch 
Size", "group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 0, "description": "Batch size for insert when the body is a 
List. 0 inserts all rows in one JDBC batch." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json
index b7084e5f2d02..bce0ae172257 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json
@@ -35,6 +35,11 @@
     "healthCheckConsumerEnabled": { "index": 8, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
     "healthCheckProducerEnabled": { "index": 9, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on producer [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "description": "One row of the 
table of the entityType per message, as the jOOQ UpdatableRecord of that class" 
},
+    "producerIn": { "carriers": [ "pojo" ], "dependsOn": [ "query" ], 
"description": "A jOOQ object, by the operation: a record of the entityType to 
store for NONE, an org.jooq.Query for EXECUTE, an org.jooq.ResultQuery (a 
select) for FETCH. Text, a Map or a List fails: there is no conversion to them. 
With the query option the SQL is that query and the body is not read" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "FETCH", "carriers": [ "list" ], "javaType": 
"org.jooq.Result" } ], "description": "NONE stores the record and EXECUTE runs 
the query, both leave the body unchanged. FETCH gives the org.jooq.Result of 
the query, a List of its records, which is empty for no row" }
+  },
   "properties": {
     "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", 
"group": "common", "label": "common", "required": false, "type": "string", 
"javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.jooq.JooqConfiguration", "configurationField": 
"configuration", "description": "JOOQ entity class" },
     "databaseConfiguration": { "index": 1, "kind": "parameter", "displayName": 
"Database Configuration", "group": "common", "label": "common", "required": 
false, "type": "object", "javaType": "org.jooq.Configuration", "deprecated": 
false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.jooq.JooqConfiguration", "configurationField": 
"configuration", "description": "To use a specific database configuration" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json
index 544a910e1097..54e42766013c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json
@@ -41,6 +41,11 @@
     "CamelJpaMaximumResults": { "index": 2, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Defines the maximum number of results to retrieve on the 
query; takes precedence over the value set on the endpoint, if any.", 
"constantName": 
"org.apache.camel.component.jpa.JpaConstants#JPA_MAXIMUM_RESULTS" },
     "CamelJpaFirstResult": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": "", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Defines the position of the first result to retrieve; 
takes precedence over the value set on the endpoint, if any.", "constantName": 
"org.apache.camel.component.jpa.JpaConstants#JPA_FIRST_RESULT" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "dependsOn": [ "query", 
"namedQuery", "nativeQuery" ], "description": "One entity of the entityType 
class per message. A query that selects columns gives one row per message: an 
Object array, or the value of a single column; a nativeQuery gives an Object 
array unless resultClass is set" },
+    "producerIn": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", 
"namedQuery", "nativeQuery" ], "byOption": [ { "option": "findEntity", "value": 
"true", "carriers": [ "value", "text" ] } ], "description": "The entity to 
persist, merge or remove, converted to the entityType class; a List or an array 
of entities needs entityType java.util.List (or java.lang.Object). Text, bytes 
or a Map fail. With findEntity, the primary key. With a query the body is not 
read: the parameters com [...]
+    "producerOut": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", 
"namedQuery", "nativeQuery", "outputTarget" ], "byOption": [ { "option": 
"usePersist", "value": "true", "carriers": [ "unchanged" ] }, { "option": 
"findEntity", "value": "true", "carriers": [ "pojo", "null" ] } ], 
"description": "The managed entity that merge returns, or a List or array of 
them; usePersist leaves the body as sent. findEntity gives the entity, or null 
when there is none. A query gives the List of [...]
+  },
   "properties": {
     "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.Class<java.lang.Object>", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Entity class name" },
     "entityManagerFactory": { "index": 1, "kind": "parameter", "displayName": 
"Entity Manager Factory", "group": "common", "label": "", "required": false, 
"type": "object", "javaType": "jakarta.persistence.EntityManagerFactory", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
EntityManagerFactory to use." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json
index f1e66c4048a5..fafb30d43184 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json
@@ -35,6 +35,10 @@
     "CamelKuduScanPredicate": { "index": 3, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": 
"org.apache.kudu.client.KuduPredicate", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The predicate for scan 
operation", "constantName": 
"org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_PREDICATE" },
     "CamelKuduScanLimit": { "index": 4, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "long", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The limit on the number of rows for scan operation", 
"constantName": 
"org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_LIMIT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "map" ], "byOption": [ { "option": 
"operation", "value": "SCAN", "carriers": [ "any" ] }, { "option": "operation", 
"value": "CREATE_TABLE", "carriers": [ "any" ] } ], "description": "For insert, 
update, upsert and delete: a Map of the column names and their values, one row, 
each value of the Java type of its column (a String for an INT32 column fails); 
delete uses only the key columns. Text such as JSON, a List or a POJO fails: 
unmarshal it into a Map fi [...]
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "SCAN", "carriers": [ "list" ], "javaType": 
"java.util.List<java.util.Map<String, Object>>" } ], "description": "Scan gives 
a List of the rows, each a Map of the column names and their values, an empty 
List for no rows. The other operations leave the body unchanged" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Host of the server to connect to" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Port of the server to connect to" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json
index 9d9f7265a9fb..4efcf074c49f 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json
@@ -34,6 +34,10 @@
   "headers": {
     "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Object", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The response returned from MyBatis in any of 
the operations. Such as INSERT could return the auto-generated key, or number 
of rows etc.", "constantName": 
"org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The argument of the 
method of the mapper, converted to its parameter type by the bean binding, so 
the text 123 fits an int parameter. With inputHeader the argument is that 
header and the body is not read" },
+    "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" 
], "description": "What the method of the mapper returns, as it declares it: a 
bean, a List of rows, a Map, a value such as the count of an update, or null 
for no row; also in the CamelMyBatisResult header. A void method leaves the 
body unchanged. With outputHeader the result goes in that header and the body 
is unchanged" }
+  },
   "properties": {
     "beanName": { "index": 0, "kind": "path", "displayName": "Bean Name", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Name of the bean with the 
MyBatis annotations. This can either by a type alias or a FQN class name." },
     "methodName": { "index": 1, "kind": "path", "displayName": "Method Name", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Name of the method on the 
bean that has the SQL query to be executed." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json
index e71af6ae3dfe..b204cc83149e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json
@@ -36,6 +36,11 @@
     "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Object", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The response returned from MyBatis in any of 
the operations. Such as INSERT could return the auto-generated key, or number 
of rows etc.", "constantName": 
"org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" },
     "CamelMyBatisStatementName": { "index": 1, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The statementName used (for example: 
insertAccount).", "constantName": 
"org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_STATEMENT_NAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" 
], "byOption": [ { "option": "useIterator", "value": "false", "carriers": [ 
"list" ] } ], "description": "One row of the select per message, as the 
resultType or resultMap of the statement maps it: a bean, a Map or a single 
value, and null for a row of only nulls. With useIterator=false a List of all 
the rows in one message; with outputHeader the row goes in that header and the 
body is null" },
+    "producerIn": { "carriers": [ "any" ], "description": "The parameter of 
the statement, given to MyBatis as it is, without type conversion: it must fit 
the parameterType, so the text 123 fails an int parameter. A bean or a Map for 
several parameters; no body runs the statement without one. Insert, Update and 
Delete run once per element of a List, an array or an Iterator, the List 
variants once with the whole List. With inputHeader the parameter is that 
header and the body is not read" },
+    "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" 
], "byOption": [ { "option": "statementType", "value": "SelectOne", "carriers": 
[ "unknown" ] }, { "option": "statementType", "value": "SelectList", 
"carriers": [ "list" ] }, { "option": "statementType", "value": "Insert", 
"carriers": [ "unchanged" ] }, { "option": "statementType", "value": 
"InsertList", "carriers": [ "unchanged" ] }, { "option": "statementType", 
"value": "Update", "carriers": [ "unchanged" ] } [...]
+  },
   "properties": {
     "statement": { "index": 0, "kind": "path", "displayName": "Statement", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The statement name in the MyBatis XML 
mapping file which maps to the query, insert, update or delete operation you 
wish to evaluate." },
     "maxMessagesPerPoll": { "index": 1, "kind": "parameter", "displayName": 
"Max Messages Per Poll", "group": "consumer", "label": "consumer", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 0, "description": "This option is 
intended to split results returned by the database pool into the batches and 
deliver them in multiple exchanges. This integer defines the maximum messages 
to deliver in single exchange [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json
index 334949141e7c..db98358463cb 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json
@@ -29,6 +29,9 @@
     "healthCheckConsumerEnabled": { "index": 2, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
     "healthCheckProducerEnabled": { "index": 3, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on producer [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "One message of the output plugin of the slot, as bytes: text 
for test_decoding, JSON for wal2json, the binary protocol for pgoutput; convert 
it to a String for the text plugins. The exchange id is the LSN of the message" 
}
+  },
   "properties": {
     "slot": { "index": 0, "kind": "path", "displayName": "Slot", "group": 
"common", "label": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Replication Slot name" },
     "host": { "index": 1, "kind": "path", "displayName": "Host", "group": 
"common", "label": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "description": "Postgres host" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json
index bfd65985c32f..6da6f6368b47 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json
@@ -31,6 +31,11 @@
   "headers": {
     "channel": { "index": 0, "kind": "header", "displayName": "", "group": 
"consumer", "label": "consumer", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the channel.", "constantName": 
"org.apache.camel.component.pgevent.PgEventConstants#HEADER_CHANNEL" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"description": "The payload of the notification as a String, empty when it was 
sent without one; the channel is in the channel header" },
+    "producerIn": { "carriers": [ "any" ], "description": "The payload of the 
notification, converted to a String: text, or bytes, a stream or a file of it; 
a Map or a POJO is sent as its toString(), so marshal it first. PostgreSQL 
takes a payload of less than 8000 bytes, and no body sends an empty payload" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "description": "To connect using hostname and port 
to the database." },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 5432, "description": "To connect using hostname and port to the 
database." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json
index 6af8b9790c35..16606cd4dc34 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json
@@ -35,6 +35,10 @@
     "CamelSqlStoredParameters": { "index": 1, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Iterator", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The parameters", "constantName": 
"org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_PARAMETERS"
 },
     "CamelSqlStoredUpdateCount": { "index": 2, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "important": true, "description": "The update count", 
"constantName": 
"org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_UPDATE_COUNT"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "batch", 
"value": "true", "carriers": [ "list", "iterator" ] }, { "option": 
"useMessageBodyForTemplate", "value": "true", "carriers": [ "text" ] } ], 
"description": "What the expressions of the IN parameters read: a :#name 
parameter takes its value from a Map body, or else from the header. With batch, 
a List or an Iterator of such bodies, one batch item each (a single Map is not 
a batch); with useMessageBodyForTemplate, [...]
+    "producerOut": { "carriers": [ "map" ], "javaType": "java.util.Map<String, 
Object>", "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "noop", 
"value": "true", "carriers": [ "unchanged" ] }, { "option": "batch", "value": 
"true", "carriers": [ "unchanged" ] } ], "description": "A Map of the names of 
the OUT and INOUT parameters and their values, with a result set the procedure 
returns under #result-set-1 (a List of Maps) and the update count under 
#update-count-1, which is al [...]
+  },
   "properties": {
     "template": { "index": 0, "kind": "path", "displayName": "Template", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"largeInput": true, "inputLanguage": "sql", "description": "Sets the stored 
procedure template to perform. You can externalize the template by using file: 
or classpath: as prefix and specify the location of [...]
     "batch": { "index": 1, "kind": "parameter", "displayName": "Batch", 
"group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "description": "Enables or disables batch mode" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc
index a6d33c8bad3d..cf61ef759ff8 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc
@@ -104,9 +104,9 @@ When using jooq as a producer you can use any of the 
following `JooqOperation` o
 [width="100%",cols="1,2",options="header"]
 |===
 | Operation | Description
-| none | Execute a query (default)
-| execute | Execute a query with no expected results
-| fetch | Execute a query and the result of the query is stored as the new 
message body
+| none | Store the entity (the record of the entity type) in the message body 
(default)
+| execute | Execute a query (an `org.jooq.Query` in the message body, or the 
`query` option) with no expected results
+| fetch | Execute a query (an `org.jooq.ResultQuery` in the message body, or 
the `query` option) and the `org.jooq.Result` of the query is stored as the new 
message body
 |===
 
 ==  Example
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc
index 80eeacaad41f..c11b5f69ffd4 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc
@@ -49,11 +49,13 @@ include::partial$component-endpoint-headers.adoc[]
 
 === Message Body
 
-The response from MyBatis will only be set as the body if it's a
-`SELECT` statement. That means, for example, for `INSERT` statements
-Camel will not replace the body. This allows you to continue routing and
-keep the original body. The response from MyBatis is always stored in
-the header with the key `CamelMyBatisResult`.
+The value the mapper method returns is set as the body, and is also stored in
+the header with the key `CamelMyBatisResult`. That is the bean, the `List` or
+the `Map` of a select (or null when there is no row), and the count of rows of 
an
+`INSERT`, `UPDATE` or `DELETE` method that returns an `int`. A `void` method
+leaves the body as it was, which allows you to continue routing with the
+original body. With the `outputHeader` option the result is stored in that
+header instead, and the body is not changed.
 
 == Examples
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc
index 34c9939ba20b..d84d40a70f92 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc
@@ -60,8 +60,9 @@ include::partial$component-endpoint-headers.adoc[]
 The response from MyBatis will only be set as the body if it's a
 `SELECT` statement. That means, for example, for `INSERT` statements
 Camel will not replace the body. This allows you to continue routing and
-keep the original body. The response from MyBatis is always stored in
-the header with the key `CamelMyBatisResult`.
+keep the original body. The response from MyBatis is stored in
+the header with the key `CamelMyBatisResult`, or in the header that the
+`outputHeader` option names, which leaves the body unchanged for a `SELECT` as 
well.
 
 == Examples
 
diff --git 
a/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json
 
b/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json
index 6e4f34d47ff7..db94b15eabb7 100644
--- 
a/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json
+++ 
b/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json
@@ -42,6 +42,10 @@
     "CamelClickHouseReadRows": { "index": 5, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "long", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The number of rows read by a query operation.", 
"constantName": 
"org.apache.camel.component.clickhouse.ClickHouseConstants#READ_ROWS" },
     "CamelClickHousePingOk": { "index": 6, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The boolean result of a ping operation.", 
"constantName": 
"org.apache.camel.component.clickhouse.ClickHouseConstants#PING_OK" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "list" ], 
"byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "text", 
"bytes", "stream", "file" ] }, { "option": "operation", "value": "PING", 
"carriers": [ "any" ] } ], "description": "The rows to insert, in the format 
option (JSONEachRow: one JSON object per line), as text, bytes, a stream or a 
file; or a List of objects whose class is registered on the Client. A Map or a 
List of Maps fails: marshal [...]
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "QUERY", "carriers": [ "text" ], "javaType": 
"java.lang.String" }, { "option": "operation", "value": "PING", "carriers": [ 
"value" ], "javaType": "java.lang.Boolean" } ], "description": "Insert leaves 
the body unchanged, with the count in the CamelClickHouseWrittenRows header. 
Query gives the result as a String in the format option (JSONEachRow: one JSON 
object per line); binary formats such [...]
+  },
   "properties": {
     "database": { "index": 0, "kind": "path", "displayName": "Database", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The ClickHouse database. A 
table may also be provided using the database.table syntax." },
     "asyncInsert": { "index": 1, "kind": "parameter", "displayName": "Async 
Insert", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to use 
ClickHouse server-side asynchronous inserts (async_insert=1)." },
diff --git 
a/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java
 
b/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java
index e9dcbac2b810..f788c6bfa659 100644
--- 
a/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java
+++ 
b/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -35,6 +38,28 @@ import org.apache.camel.util.ObjectHelper;
 @UriEndpoint(firstVersion = "4.22.0", scheme = "clickhouse", title = 
"ClickHouse",
              syntax = "clickhouse:database", category = { Category.DATABASE, 
Category.BIGDATA },
              producerOnly = true, headersClass = ClickHouseConstants.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE, Carrier.LIST },
+                                  byOption = {
+                                          @BodyType.When(option = "operation", 
value = "QUERY",
+                                                         carriers = {
+                                                                 Carrier.TEXT, 
Carrier.BYTES, Carrier.STREAM,
+                                                                 Carrier.FILE 
}),
+                                          @BodyType.When(option = "operation", 
value = "PING", carriers = Carrier.ANY) },
+                                  description = "The rows to insert, in the 
format option (JSONEachRow: one JSON object per"
+                                                + " line), as text, bytes, a 
stream or a file; or a List of objects whose"
+                                                + " class is registered on the 
Client. A Map or a List of Maps fails: marshal"
+                                                + " it first. Query takes the 
SQL statement"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "QUERY", carriers = Carrier.TEXT,
+                                                          javaType = 
"java.lang.String"),
+                                           @BodyType.When(option = 
"operation", value = "PING", carriers = Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean") },
+                                   description = "Insert leaves the body 
unchanged, with the count in the"
+                                                 + " 
CamelClickHouseWrittenRows header. Query gives the result as a String"
+                                                 + " in the format option 
(JSONEachRow: one JSON object per line); binary"
+                                                 + " formats such as RowBinary 
do not survive the String. Ping gives a"
+                                                 + " Boolean. The 
CamelClickHouseOperation header overrides the operation"))
 public class ClickHouseEndpoint extends DefaultEndpoint {
 
     private Client client;
diff --git 
a/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json
 
b/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json
index e3543bc15f93..c01654c60035 100644
--- 
a/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json
+++ 
b/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json
@@ -30,6 +30,10 @@
   "headers": {
     "CamelDrillQuery": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The drill query", "constantName": 
"org.apache.camel.component.drill.DrillConstants#DRILL_QUERY" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the query comes from the CamelDrillQuery header, and a query in the body 
without that header fails" },
+    "producerOut": { "carriers": [ "list" ], "javaType": 
"java.util.List<java.util.Map<String, Object>>", "description": "The rows of 
the query: a List of Maps of the column names (case insensitive) and their 
values, an empty List for no rows. A statement such as CREATE TABLE AS, DROP or 
ALTER SESSION gives the one row Drill answers with, such as ok and summary" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Host name or IP address" },
     "clusterId": { "index": 1, "kind": "parameter", "displayName": "Cluster 
Id", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Cluster ID 
https:\/\/drill.apache.org\/docs\/using-the-jdbc-driver\/#determining-the-cluster-id"
 },
diff --git 
a/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java
 
b/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java
index 1c71dd656e31..a3d785986800 100644
--- 
a/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java
+++ 
b/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java
@@ -26,6 +26,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.component.drill.util.StringUtils;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -40,6 +43,15 @@ import 
org.springframework.jdbc.core.RowMapperResultSetExtractor;
  */
 @UriEndpoint(firstVersion = "2.19.0", scheme = "drill", title = "Drill", 
syntax = "drill:host", producerOnly = true,
              category = { Category.DATABASE, Category.BIGDATA }, headersClass 
= DrillConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The body is not read: the 
query comes from the CamelDrillQuery header,"
+                                                + " and a query in the body 
without that header fails"),
+           producerOut = @BodyType(value = Carrier.LIST,
+                                   javaType = 
"java.util.List<java.util.Map<String, Object>>",
+                                   description = "The rows of the query: a 
List of Maps of the column names (case"
+                                                 + " insensitive) and their 
values, an empty List for no rows. A statement"
+                                                 + " such as CREATE TABLE AS, 
DROP or ALTER SESSION gives the one row Drill"
+                                                 + " answers with, such as ok 
and summary"))
 public class DrillEndpoint extends DefaultPollingEndpoint implements 
EndpointServiceLocation {
 
     @UriPath(description = "Host name or IP address")
diff --git 
a/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json
 
b/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json
index ae7b10fe972c..b018b667caae 100644
--- 
a/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json
+++ 
b/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json
@@ -39,6 +39,10 @@
     "CamelDuckDbRowsRead": { "index": 5, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "long", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The number of rows returned by a query.", 
"constantName": "org.apache.camel.component.duckdb.DuckDbConstants#ROWS_READ" },
     "CamelDuckDbPingOk": { "index": 6, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "boolean", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The boolean result of a ping operation.", 
"constantName": "org.apache.camel.component.duckdb.DuckDbConstants#PING_OK" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"dependsOn": [ "query" ], "byOption": [ { "option": "operation", "value": 
"INSERT", "carriers": [ "list" ] }, { "option": "operation", "value": "COPY", 
"carriers": [ "file", "text" ] }, { "option": "operation", "value": "PING", 
"carriers": [ "any" ] } ], "description": "The SQL statement as text, or bytes, 
a stream or a file of it; the query option or the CamelDuckDbQuery header takes 
its place. Insert takes a List of [...]
+    "producerOut": { "carriers": [ "value" ], "javaType": "java.lang.Long", 
"byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "list" 
], "javaType": "java.util.List<java.util.Map<String, Object>>" }, { "option": 
"operation", "value": "PING", "carriers": [ "value" ], "javaType": 
"java.lang.Boolean" }, { "option": "resultFormat", "value": "JSON", "carriers": 
[ "text", "value" ] } ], "description": "The count of rows written or affected 
as a Long, also in the CamelDuckDb [...]
+  },
   "properties": {
     "databasePath": { "index": 0, "kind": "path", "displayName": "Database 
Path", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Database path, either :memory: or a relative 
or absolute file path." },
     "batchSize": { "index": 1, "kind": "parameter", "displayName": "Batch 
Size", "group": "producer", "label": "", "required": false, "type": "integer", 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 0, "description": "Batch size for insert when the body is a 
List. 0 inserts all rows in one JDBC batch." },
diff --git 
a/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java
 
b/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java
index 80895ed53157..b41e0173c322 100644
--- 
a/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java
+++ 
b/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java
@@ -26,6 +26,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
@@ -39,6 +42,30 @@ import org.apache.camel.util.ObjectHelper;
 @UriEndpoint(firstVersion = "4.22.0", scheme = "duckdb", title = "DuckDB",
              syntax = "duckdb:databasePath", category = { Category.DATABASE, 
Category.BIGDATA },
              producerOnly = true, headersClass = DuckDbConstants.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  dependsOn = "query",
+                                  byOption = {
+                                          @BodyType.When(option = "operation", 
value = "INSERT", carriers = Carrier.LIST),
+                                          @BodyType.When(option = "operation", 
value = "COPY",
+                                                         carriers = { 
Carrier.FILE, Carrier.TEXT }),
+                                          @BodyType.When(option = "operation", 
value = "PING", carriers = Carrier.ANY) },
+                                  description = "The SQL statement as text, or 
bytes, a stream or a file of it; the query"
+                                                + " option or the 
CamelDuckDbQuery header takes its place. Insert takes a List"
+                                                + " of Maps of the column 
names and their values (a Map alone fails), copy a"
+                                                + " File or the path of the 
csv, parquet or json file to load"),
+           producerOut = @BodyType(value = Carrier.VALUE, javaType = 
"java.lang.Long",
+                                   byOption = {
+                                           @BodyType.When(option = 
"operation", value = "QUERY", carriers = Carrier.LIST,
+                                                          javaType = 
"java.util.List<java.util.Map<String, Object>>"),
+                                           @BodyType.When(option = 
"operation", value = "PING", carriers = Carrier.VALUE,
+                                                          javaType = 
"java.lang.Boolean"),
+                                           @BodyType.When(option = 
"resultFormat", value = "JSON",
+                                                          carriers = { 
Carrier.TEXT, Carrier.VALUE }) },
+                                   description = "The count of rows written or 
affected as a Long, also in the"
+                                                 + " CamelDuckDbRowsWritten 
header. Query gives the rows as a List of Maps"
+                                                 + " of the column names and 
their values (a JSON array String with"
+                                                 + " resultFormat=JSON), ping 
a Boolean. The CamelDuckDbOperation header"
+                                                 + " overrides the operation"))
 public class DuckDbEndpoint extends DefaultEndpoint {
 
     private final ReentrantLock connectionLock = new ReentrantLock();
diff --git 
a/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json
 
b/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json
index b7084e5f2d02..bce0ae172257 100644
--- 
a/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json
+++ 
b/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json
@@ -35,6 +35,11 @@
     "healthCheckConsumerEnabled": { "index": 8, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
     "healthCheckProducerEnabled": { "index": 9, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on producer [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "description": "One row of the 
table of the entityType per message, as the jOOQ UpdatableRecord of that class" 
},
+    "producerIn": { "carriers": [ "pojo" ], "dependsOn": [ "query" ], 
"description": "A jOOQ object, by the operation: a record of the entityType to 
store for NONE, an org.jooq.Query for EXECUTE, an org.jooq.ResultQuery (a 
select) for FETCH. Text, a Map or a List fails: there is no conversion to them. 
With the query option the SQL is that query and the body is not read" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "FETCH", "carriers": [ "list" ], "javaType": 
"org.jooq.Result" } ], "description": "NONE stores the record and EXECUTE runs 
the query, both leave the body unchanged. FETCH gives the org.jooq.Result of 
the query, a List of its records, which is empty for no row" }
+  },
   "properties": {
     "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", 
"group": "common", "label": "common", "required": false, "type": "string", 
"javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.jooq.JooqConfiguration", "configurationField": 
"configuration", "description": "JOOQ entity class" },
     "databaseConfiguration": { "index": 1, "kind": "parameter", "displayName": 
"Database Configuration", "group": "common", "label": "common", "required": 
false, "type": "object", "javaType": "org.jooq.Configuration", "deprecated": 
false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.jooq.JooqConfiguration", "configurationField": 
"configuration", "description": "To use a specific database configuration" },
diff --git a/components/camel-jooq/src/main/docs/jooq-component.adoc 
b/components/camel-jooq/src/main/docs/jooq-component.adoc
index a6d33c8bad3d..cf61ef759ff8 100644
--- a/components/camel-jooq/src/main/docs/jooq-component.adoc
+++ b/components/camel-jooq/src/main/docs/jooq-component.adoc
@@ -104,9 +104,9 @@ When using jooq as a producer you can use any of the 
following `JooqOperation` o
 [width="100%",cols="1,2",options="header"]
 |===
 | Operation | Description
-| none | Execute a query (default)
-| execute | Execute a query with no expected results
-| fetch | Execute a query and the result of the query is stored as the new 
message body
+| none | Store the entity (the record of the entity type) in the message body 
(default)
+| execute | Execute a query (an `org.jooq.Query` in the message body, or the 
`query` option) with no expected results
+| fetch | Execute a query (an `org.jooq.ResultQuery` in the message body, or 
the `query` option) and the `org.jooq.Result` of the query is stored as the new 
message body
 |===
 
 ==  Example
diff --git 
a/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java
 
b/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java
index 9e25470fcfb2..a8b50cb6c5a1 100644
--- 
a/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java
+++ 
b/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java
@@ -24,6 +24,9 @@ import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.support.ScheduledPollEndpoint;
@@ -35,6 +38,20 @@ import org.jooq.ResultQuery;
  */
 @UriEndpoint(firstVersion = "3.0.0", scheme = "jooq", syntax = 
"jooq:entityType", title = "JOOQ",
              category = { Category.DATABASE })
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO,
+                                   description = "One row of the table of the 
entityType per message, as the jOOQ"
+                                                 + " UpdatableRecord of that 
class"),
+           producerIn = @BodyType(value = Carrier.POJO, dependsOn = "query",
+                                  description = "A jOOQ object, by the 
operation: a record of the entityType to store for"
+                                                + " NONE, an org.jooq.Query 
for EXECUTE, an org.jooq.ResultQuery (a select)"
+                                                + " for FETCH. Text, a Map or 
a List fails: there is no conversion to them."
+                                                + " With the query option the 
SQL is that query and the body is not read"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = @BodyType.When(option = 
"operation", value = "FETCH", carriers = Carrier.LIST,
+                                                             javaType = 
"org.jooq.Result"),
+                                   description = "NONE stores the record and 
EXECUTE runs the query, both leave the body"
+                                                 + " unchanged. FETCH gives 
the org.jooq.Result of the query, a List of its"
+                                                 + " records, which is empty 
for no row"))
 public class JooqEndpoint extends ScheduledPollEndpoint {
 
     private Expression producerExpression;
diff --git 
a/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json
 
b/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json
index 544a910e1097..54e42766013c 100644
--- 
a/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json
+++ 
b/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json
@@ -41,6 +41,11 @@
     "CamelJpaMaximumResults": { "index": 2, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Defines the maximum number of results to retrieve on the 
query; takes precedence over the value set on the endpoint, if any.", 
"constantName": 
"org.apache.camel.component.jpa.JpaConstants#JPA_MAXIMUM_RESULTS" },
     "CamelJpaFirstResult": { "index": 3, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": "", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Defines the position of the first result to retrieve; 
takes precedence over the value set on the endpoint, if any.", "constantName": 
"org.apache.camel.component.jpa.JpaConstants#JPA_FIRST_RESULT" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "dependsOn": [ "query", 
"namedQuery", "nativeQuery" ], "description": "One entity of the entityType 
class per message. A query that selects columns gives one row per message: an 
Object array, or the value of a single column; a nativeQuery gives an Object 
array unless resultClass is set" },
+    "producerIn": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", 
"namedQuery", "nativeQuery" ], "byOption": [ { "option": "findEntity", "value": 
"true", "carriers": [ "value", "text" ] } ], "description": "The entity to 
persist, merge or remove, converted to the entityType class; a List or an array 
of entities needs entityType java.util.List (or java.lang.Object). Text, bytes 
or a Map fail. With findEntity, the primary key. With a query the body is not 
read: the parameters com [...]
+    "producerOut": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", 
"namedQuery", "nativeQuery", "outputTarget" ], "byOption": [ { "option": 
"usePersist", "value": "true", "carriers": [ "unchanged" ] }, { "option": 
"findEntity", "value": "true", "carriers": [ "pojo", "null" ] } ], 
"description": "The managed entity that merge returns, or a List or array of 
them; usePersist leaves the body as sent. findEntity gives the entity, or null 
when there is none. A query gives the List of [...]
+  },
   "properties": {
     "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.Class<java.lang.Object>", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Entity class name" },
     "entityManagerFactory": { "index": 1, "kind": "parameter", "displayName": 
"Entity Manager Factory", "group": "common", "label": "", "required": false, 
"type": "object", "javaType": "jakarta.persistence.EntityManagerFactory", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
EntityManagerFactory to use." },
diff --git 
a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java
 
b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java
index 3d0eba7a8e2a..bbb5e347c372 100644
--- 
a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java
+++ 
b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java
@@ -31,6 +31,9 @@ import org.apache.camel.InvalidPayloadRuntimeException;
 import org.apache.camel.PollingConsumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -48,6 +51,33 @@ import 
org.springframework.orm.jpa.SharedEntityManagerCreator;
  */
 @UriEndpoint(firstVersion = "1.0.0", scheme = "jpa", title = "JPA", syntax = 
"jpa:entityType",
              category = { Category.DATABASE }, headersClass = 
JpaConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, dependsOn = { 
"query", "namedQuery", "nativeQuery" },
+                                   description = "One entity of the entityType 
class per message. A query that selects"
+                                                 + " columns gives one row per 
message: an Object array, or the value of a"
+                                                 + " single column; a 
nativeQuery gives an Object array unless resultClass"
+                                                 + " is set"),
+           producerIn = @BodyType(value = { Carrier.POJO, Carrier.LIST },
+                                  dependsOn = { "query", "namedQuery", 
"nativeQuery" },
+                                  byOption = @BodyType.When(option = 
"findEntity", value = "true",
+                                                            carriers = { 
Carrier.VALUE, Carrier.TEXT }),
+                                  description = "The entity to persist, merge 
or remove, converted to the entityType class;"
+                                                + " a List or an array of 
entities needs entityType java.util.List (or"
+                                                + " java.lang.Object). Text, 
bytes or a Map fail. With findEntity, the primary"
+                                                + " key. With a query the body 
is not read: the parameters come from the"
+                                                + " parameters option or the 
CamelJpaParameters header"),
+           producerOut = @BodyType(value = { Carrier.POJO, Carrier.LIST },
+                                   dependsOn = { "query", "namedQuery", 
"nativeQuery", "outputTarget" },
+                                   byOption = {
+                                           @BodyType.When(option = 
"usePersist", value = "true",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"findEntity", value = "true",
+                                                          carriers = { 
Carrier.POJO, Carrier.NULL }) },
+                                   description = "The managed entity that 
merge returns, or a List or array of them;"
+                                                 + " usePersist leaves the 
body as sent. findEntity gives the entity, or"
+                                                 + " null when there is none. 
A query gives the List of its results"
+                                                 + " (entities, Object arrays 
or values), the one result with singleResult,"
+                                                 + " or the count of an update 
or delete as an Integer; with outputTarget the"
+                                                 + " result goes to that 
header (or property:name) and the body is unchanged"))
 public class JpaEndpoint extends ScheduledPollEndpoint {
 
     @UriParam
diff --git 
a/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json
 
b/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json
index f1e66c4048a5..fafb30d43184 100644
--- 
a/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json
+++ 
b/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json
@@ -35,6 +35,10 @@
     "CamelKuduScanPredicate": { "index": 3, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": 
"org.apache.kudu.client.KuduPredicate", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The predicate for scan 
operation", "constantName": 
"org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_PREDICATE" },
     "CamelKuduScanLimit": { "index": 4, "kind": "header", "displayName": "", 
"group": "producer", "label": "", "required": false, "javaType": "long", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The limit on the number of rows for scan operation", 
"constantName": 
"org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_LIMIT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "map" ], "byOption": [ { "option": 
"operation", "value": "SCAN", "carriers": [ "any" ] }, { "option": "operation", 
"value": "CREATE_TABLE", "carriers": [ "any" ] } ], "description": "For insert, 
update, upsert and delete: a Map of the column names and their values, one row, 
each value of the Java type of its column (a String for an INT32 column fails); 
delete uses only the key columns. Text such as JSON, a List or a POJO fails: 
unmarshal it into a Map fi [...]
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "SCAN", "carriers": [ "list" ], "javaType": 
"java.util.List<java.util.Map<String, Object>>" } ], "description": "Scan gives 
a List of the rows, each a Map of the column names and their values, an empty 
List for no rows. The other operations leave the body unchanged" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Host of the server to connect to" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Port of the server to connect to" },
diff --git 
a/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java
 
b/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java
index 0e03d38719a1..ae73220f3bd2 100644
--- 
a/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java
+++ 
b/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -42,6 +45,24 @@ import org.slf4j.LoggerFactory;
              title = "Kudu", syntax = "kudu:host:port/tableName",
              category = { Category.DATABASE, Category.IOT, Category.CLOUD }, 
producerOnly = true,
              headersClass = KuduConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.MAP,
+                                  byOption = {
+                                          @BodyType.When(option = "operation", 
value = "SCAN", carriers = Carrier.ANY),
+                                          @BodyType.When(option = "operation", 
value = "CREATE_TABLE",
+                                                         carriers = 
Carrier.ANY) },
+                                  description = "For insert, update, upsert 
and delete: a Map of the column names and"
+                                                + " their values, one row, 
each value of the Java type of its column (a"
+                                                + " String for an INT32 column 
fails); delete uses only the key columns."
+                                                + " Text such as JSON, a List 
or a POJO fails: unmarshal it into a Map"
+                                                + " first. Scan and 
create_table do not read the body: they take the"
+                                                + " CamelKuduScan* and the 
CamelKuduSchema and CamelKuduTableOptions"
+                                                + " headers. The operation 
must be set"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = @BodyType.When(option = 
"operation", value = "SCAN", carriers = Carrier.LIST,
+                                                             javaType = 
"java.util.List<java.util.Map<String, Object>>"),
+                                   description = "Scan gives a List of the 
rows, each a Map of the column names and their"
+                                                 + " values, an empty List for 
no rows. The other operations leave the body"
+                                                 + " unchanged"))
 public class KuduEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(KuduEndpoint.class);
diff --git 
a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json
 
b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json
index 9d9f7265a9fb..4efcf074c49f 100644
--- 
a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json
+++ 
b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json
@@ -34,6 +34,10 @@
   "headers": {
     "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Object", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The response returned from MyBatis in any of 
the operations. Such as INSERT could return the auto-generated key, or number 
of rows etc.", "constantName": 
"org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "description": "The argument of the 
method of the mapper, converted to its parameter type by the bean binding, so 
the text 123 fits an int parameter. With inputHeader the argument is that 
header and the body is not read" },
+    "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" 
], "description": "What the method of the mapper returns, as it declares it: a 
bean, a List of rows, a Map, a value such as the count of an update, or null 
for no row; also in the CamelMyBatisResult header. A void method leaves the 
body unchanged. With outputHeader the result goes in that header and the body 
is unchanged" }
+  },
   "properties": {
     "beanName": { "index": 0, "kind": "path", "displayName": "Bean Name", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Name of the bean with the 
MyBatis annotations. This can either by a type alias or a FQN class name." },
     "methodName": { "index": 1, "kind": "path", "displayName": "Method Name", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Name of the method on the 
bean that has the SQL query to be executed." },
diff --git 
a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json
 
b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json
index e71af6ae3dfe..b204cc83149e 100644
--- 
a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json
+++ 
b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json
@@ -36,6 +36,11 @@
     "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"Object", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The response returned from MyBatis in any of 
the operations. Such as INSERT could return the auto-generated key, or number 
of rows etc.", "constantName": 
"org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" },
     "CamelMyBatisStatementName": { "index": 1, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The statementName used (for example: 
insertAccount).", "constantName": 
"org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_STATEMENT_NAME" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" 
], "byOption": [ { "option": "useIterator", "value": "false", "carriers": [ 
"list" ] } ], "description": "One row of the select per message, as the 
resultType or resultMap of the statement maps it: a bean, a Map or a single 
value, and null for a row of only nulls. With useIterator=false a List of all 
the rows in one message; with outputHeader the row goes in that header and the 
body is null" },
+    "producerIn": { "carriers": [ "any" ], "description": "The parameter of 
the statement, given to MyBatis as it is, without type conversion: it must fit 
the parameterType, so the text 123 fails an int parameter. A bean or a Map for 
several parameters; no body runs the statement without one. Insert, Update and 
Delete run once per element of a List, an array or an Iterator, the List 
variants once with the whole List. With inputHeader the parameter is that 
header and the body is not read" },
+    "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" 
], "byOption": [ { "option": "statementType", "value": "SelectOne", "carriers": 
[ "unknown" ] }, { "option": "statementType", "value": "SelectList", 
"carriers": [ "list" ] }, { "option": "statementType", "value": "Insert", 
"carriers": [ "unchanged" ] }, { "option": "statementType", "value": 
"InsertList", "carriers": [ "unchanged" ] }, { "option": "statementType", 
"value": "Update", "carriers": [ "unchanged" ] } [...]
+  },
   "properties": {
     "statement": { "index": 0, "kind": "path", "displayName": "Statement", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The statement name in the MyBatis XML 
mapping file which maps to the query, insert, update or delete operation you 
wish to evaluate." },
     "maxMessagesPerPoll": { "index": 1, "kind": "parameter", "displayName": 
"Max Messages Per Poll", "group": "consumer", "label": "consumer", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 0, "description": "This option is 
intended to split results returned by the database pool into the batches and 
deliver them in multiple exchanges. This integer defines the maximum messages 
to deliver in single exchange [...]
diff --git a/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc 
b/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc
index 80eeacaad41f..c11b5f69ffd4 100644
--- a/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc
+++ b/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc
@@ -49,11 +49,13 @@ include::partial$component-endpoint-headers.adoc[]
 
 === Message Body
 
-The response from MyBatis will only be set as the body if it's a
-`SELECT` statement. That means, for example, for `INSERT` statements
-Camel will not replace the body. This allows you to continue routing and
-keep the original body. The response from MyBatis is always stored in
-the header with the key `CamelMyBatisResult`.
+The value the mapper method returns is set as the body, and is also stored in
+the header with the key `CamelMyBatisResult`. That is the bean, the `List` or
+the `Map` of a select (or null when there is no row), and the count of rows of 
an
+`INSERT`, `UPDATE` or `DELETE` method that returns an `int`. A `void` method
+leaves the body as it was, which allows you to continue routing with the
+original body. With the `outputHeader` option the result is stored in that
+header instead, and the body is not changed.
 
 == Examples
 
diff --git a/components/camel-mybatis/src/main/docs/mybatis-component.adoc 
b/components/camel-mybatis/src/main/docs/mybatis-component.adoc
index 34c9939ba20b..d84d40a70f92 100644
--- a/components/camel-mybatis/src/main/docs/mybatis-component.adoc
+++ b/components/camel-mybatis/src/main/docs/mybatis-component.adoc
@@ -60,8 +60,9 @@ include::partial$component-endpoint-headers.adoc[]
 The response from MyBatis will only be set as the body if it's a
 `SELECT` statement. That means, for example, for `INSERT` statements
 Camel will not replace the body. This allows you to continue routing and
-keep the original body. The response from MyBatis is always stored in
-the header with the key `CamelMyBatisResult`.
+keep the original body. The response from MyBatis is stored in
+the header with the key `CamelMyBatisResult`, or in the header that the
+`outputHeader` option names, which leaves the body unchanged for a `SELECT` as 
well.
 
 == Examples
 
diff --git 
a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java
 
b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java
index 9155e9d0f155..474b0760ea33 100644
--- 
a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java
+++ 
b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriPath;
@@ -33,6 +36,16 @@ import static 
org.apache.camel.component.mybatis.MyBatisConstants.SCHEME_MYBATIS
 @UriEndpoint(firstVersion = "2.22.0", scheme = SCHEME_MYBATIS_BEAN, title = 
"MyBatis Bean",
              syntax = "mybatis-bean:beanName:methodName", producerOnly = true, 
category = { Category.DATABASE },
              headersClass = MyBatisConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The argument of the method of 
the mapper, converted to its parameter type"
+                                                + " by the bean binding, so 
the text 123 fits an int parameter. With"
+                                                + " inputHeader the argument 
is that header and the body is not read"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN, dependsOn = 
"outputHeader",
+                                   description = "What the method of the 
mapper returns, as it declares it: a bean, a List of"
+                                                 + " rows, a Map, a value such 
as the count of an update, or null for no row;"
+                                                 + " also in the 
CamelMyBatisResult header. A void method leaves the body"
+                                                 + " unchanged. With 
outputHeader the result goes in that header and the body"
+                                                 + " is unchanged"))
 public class MyBatisBeanEndpoint extends BaseMyBatisEndpoint {
 
     @UriPath
diff --git 
a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
 
b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
index 1f56faf017ec..eeef936bc9a3 100644
--- 
a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
+++ 
b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -34,6 +37,44 @@ import static 
org.apache.camel.component.mybatis.MyBatisConstants.SCHEME_MYBATIS
  */
 @UriEndpoint(firstVersion = "2.7.0", scheme = SCHEME_MYBATIS, title = 
"MyBatis", syntax = "mybatis:statement",
              category = { Category.DATABASE }, headersClass = 
MyBatisConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.UNKNOWN, dependsOn = 
"outputHeader",
+                                   byOption = @BodyType.When(option = 
"useIterator", value = "false", carriers = Carrier.LIST),
+                                   description = "One row of the select per 
message, as the resultType or resultMap of the"
+                                                 + " statement maps it: a 
bean, a Map or a single value, and null for a row of"
+                                                 + " only nulls. With 
useIterator=false a List of all the rows in one message;"
+                                                 + " with outputHeader the row 
goes in that header and the body is null"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The parameter of the 
statement, given to MyBatis as it is, without type"
+                                                + " conversion: it must fit 
the parameterType, so the text 123 fails an int"
+                                                + " parameter. A bean or a Map 
for several parameters; no body runs the"
+                                                + " statement without one. 
Insert, Update and Delete run once per element of"
+                                                + " a List, an array or an 
Iterator, the List variants once with the whole"
+                                                + " List. With inputHeader the 
parameter is that header and the body is not"
+                                                + " read"),
+           producerOut = @BodyType(value = Carrier.UNKNOWN, dependsOn = 
"outputHeader",
+                                   byOption = {
+                                           @BodyType.When(option = 
"statementType", value = "SelectOne",
+                                                          carriers = 
Carrier.UNKNOWN),
+                                           @BodyType.When(option = 
"statementType", value = "SelectList",
+                                                          carriers = 
Carrier.LIST),
+                                           @BodyType.When(option = 
"statementType", value = "Insert",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"statementType", value = "InsertList",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"statementType", value = "Update",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"statementType", value = "UpdateList",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"statementType", value = "Delete",
+                                                          carriers = 
Carrier.UNCHANGED),
+                                           @BodyType.When(option = 
"statementType", value = "DeleteList",
+                                                          carriers = 
Carrier.UNCHANGED) },
+                                   description = "By the statementType, which 
the producer needs: SelectOne gives the one"
+                                                 + " row as the statement maps 
it (a bean, a Map or a value), or null for no"
+                                                 + " row; SelectList a List of 
the rows. Insert, Update and Delete leave the"
+                                                 + " body unchanged, with the 
count of rows in the CamelMyBatisResult header."
+                                                 + " With outputHeader the 
result goes in that header and the body is"
+                                                 + " unchanged"))
 public class MyBatisEndpoint extends BaseMyBatisEndpoint {
 
     @UriPath
diff --git 
a/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json
 
b/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json
index 334949141e7c..db98358463cb 100644
--- 
a/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json
+++ 
b/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json
@@ -29,6 +29,9 @@
     "healthCheckConsumerEnabled": { "index": 2, "kind": "property", 
"displayName": "Health Check Consumer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all consumer based health checks 
from this component" },
     "healthCheckProducerEnabled": { "index": 3, "kind": "property", 
"displayName": "Health Check Producer Enabled", "group": "health", "label": 
"health", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Used for enabling or disabling all producer based health checks 
from this component. Notice: Camel has by default disabled all producer based 
health-checks. You can turn on producer [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", 
"description": "One message of the output plugin of the slot, as bytes: text 
for test_decoding, JSON for wal2json, the binary protocol for pgoutput; convert 
it to a String for the text plugins. The exchange id is the LSN of the message" 
}
+  },
   "properties": {
     "slot": { "index": 0, "kind": "path", "displayName": "Slot", "group": 
"common", "label": "common", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Replication Slot name" },
     "host": { "index": 1, "kind": "path", "displayName": "Host", "group": 
"common", "label": "common", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "description": "Postgres host" },
diff --git 
a/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java
 
b/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java
index f70b08c0225f..76de2f10d477 100644
--- 
a/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java
+++ 
b/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java
@@ -30,6 +30,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -45,6 +48,11 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(firstVersion = "3.0.0", scheme = "pg-replication-slot", title = 
"PostgreSQL Replication Slot",
              syntax = 
"pg-replication-slot:host:port/database/slot:outputPlugin",
              category = { Category.DATABASE }, consumerOnly = true)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]",
+                                   description = "One message of the output 
plugin of the slot, as bytes: text for"
+                                                 + " test_decoding, JSON for 
wal2json, the binary protocol for pgoutput;"
+                                                 + " convert it to a String 
for the text plugins. The exchange id is the LSN"
+                                                 + " of the message"))
 public class PgReplicationSlotEndpoint extends ScheduledPollEndpoint {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(PgReplicationSlotEndpoint.class);
diff --git 
a/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json
 
b/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json
index bfd65985c32f..6da6f6368b47 100644
--- 
a/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json
+++ 
b/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json
@@ -31,6 +31,11 @@
   "headers": {
     "channel": { "index": 0, "kind": "header", "displayName": "", "group": 
"consumer", "label": "consumer", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The name of the channel.", "constantName": 
"org.apache.camel.component.pgevent.PgEventConstants#HEADER_CHANNEL" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"description": "The payload of the notification as a String, empty when it was 
sent without one; the channel is in the channel header" },
+    "producerIn": { "carriers": [ "any" ], "description": "The payload of the 
notification, converted to a String: text, or bytes, a stream or a file of it; 
a Map or a POJO is sent as its toString(), so marshal it first. PostgreSQL 
takes a payload of less than 8000 bytes, and no body sends an empty payload" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "localhost", "description": "To connect using hostname and port 
to the database." },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 5432, "description": "To connect using hostname and port to the 
database." },
diff --git 
a/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java
 
b/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java
index 1fe9dc6b7e0b..f515fe883fd1 100644
--- 
a/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java
+++ 
b/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java
@@ -28,6 +28,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
@@ -46,6 +49,15 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(firstVersion = "2.15.0", scheme = "pgevent", title = "PostgreSQL 
Event",
              syntax = "pgevent:host:port/database/channel",
              category = { Category.DATABASE }, headersClass = 
PgEventConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String",
+                                   description = "The payload of the 
notification as a String, empty when it was sent"
+                                                 + " without one; the channel 
is in the channel header"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The payload of the 
notification, converted to a String: text, or bytes,"
+                                                + " a stream or a file of it; 
a Map or a POJO is sent as its toString(), so"
+                                                + " marshal it first. 
PostgreSQL takes a payload of less than 8000 bytes,"
+                                                + " and no body sends an empty 
payload"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED))
 public class PgEventEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(PgEventEndpoint.class);
diff --git 
a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json
 
b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json
index 6af8b9790c35..16606cd4dc34 100644
--- 
a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json
+++ 
b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json
@@ -35,6 +35,10 @@
     "CamelSqlStoredParameters": { "index": 1, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"Iterator", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The parameters", "constantName": 
"org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_PARAMETERS"
 },
     "CamelSqlStoredUpdateCount": { "index": 2, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "important": true, "description": "The update count", 
"constantName": 
"org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_UPDATE_COUNT"
 }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "batch", 
"value": "true", "carriers": [ "list", "iterator" ] }, { "option": 
"useMessageBodyForTemplate", "value": "true", "carriers": [ "text" ] } ], 
"description": "What the expressions of the IN parameters read: a :#name 
parameter takes its value from a Map body, or else from the header. With batch, 
a List or an Iterator of such bodies, one batch item each (a single Map is not 
a batch); with useMessageBodyForTemplate, [...]
+    "producerOut": { "carriers": [ "map" ], "javaType": "java.util.Map<String, 
Object>", "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "noop", 
"value": "true", "carriers": [ "unchanged" ] }, { "option": "batch", "value": 
"true", "carriers": [ "unchanged" ] } ], "description": "A Map of the names of 
the OUT and INOUT parameters and their values, with a result set the procedure 
returns under #result-set-1 (a List of Maps) and the update count under 
#update-count-1, which is al [...]
+  },
   "properties": {
     "template": { "index": 0, "kind": "path", "displayName": "Template", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"largeInput": true, "inputLanguage": "sql", "description": "Sets the stored 
procedure template to perform. You can externalize the template by using file: 
or classpath: as prefix and specify the location of [...]
     "batch": { "index": 1, "kind": "parameter", "displayName": "Batch", 
"group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "description": "Enables or disables batch mode" },
diff --git 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java
 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java
index 2ded97421b56..d1628d12f490 100644
--- 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java
+++ 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java
@@ -28,6 +28,9 @@ import org.apache.camel.Producer;
 import org.apache.camel.component.sql.SqlServiceLocationHelper;
 import org.apache.camel.component.sql.stored.template.TemplateParser;
 import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -44,6 +47,28 @@ import org.springframework.jdbc.core.JdbcTemplate;
  */
 @UriEndpoint(firstVersion = "2.17.0", scheme = "sql-stored", title = "SQL 
Stored Procedure", syntax = "sql-stored:template",
              producerOnly = true, category = { Category.DATABASE }, 
headersClass = SqlStoredConstants.class)
+@BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
+                                  byOption = {
+                                          @BodyType.When(option = "batch", 
value = "true",
+                                                         carriers = { 
Carrier.LIST, Carrier.ITERATOR }),
+                                          @BodyType.When(option = 
"useMessageBodyForTemplate", value = "true",
+                                                         carriers = 
Carrier.TEXT) },
+                                  description = "What the expressions of the 
IN parameters read: a :#name parameter takes"
+                                                + " its value from a Map body, 
or else from the header. With batch, a List or"
+                                                + " an Iterator of such 
bodies, one batch item each (a single Map is not a"
+                                                + " batch); with 
useMessageBodyForTemplate, the template as text, with the"
+                                                + " parameters in the 
CamelSqlStoredParameters header"),
+           producerOut = @BodyType(value = Carrier.MAP, javaType = 
"java.util.Map<String, Object>",
+                                   dependsOn = "outputHeader",
+                                   byOption = {
+                                           @BodyType.When(option = "noop", 
value = "true", carriers = Carrier.UNCHANGED),
+                                           @BodyType.When(option = "batch", 
value = "true", carriers = Carrier.UNCHANGED) },
+                                   description = "A Map of the names of the 
OUT and INOUT parameters and their values, with"
+                                                 + " a result set the 
procedure returns under #result-set-1 (a List of Maps)"
+                                                 + " and the update count 
under #update-count-1, which is also in the"
+                                                 + " CamelSqlStoredUpdateCount 
header. With outputHeader the Map is in that"
+                                                 + " header and the body is 
unchanged; batch leaves the body unchanged, with"
+                                                 + " the total update count in 
the header"))
 public class SqlStoredEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
     private CallableStatementWrapperFactory wrapperFactory;

Reply via email to