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


The following commit(s) were added to refs/heads/main by this push:
     new 3dcae5b56bf9 CAMEL-25074: camel-sql - say in the outputType 
description that a StreamList body is an Iterator with no size
3dcae5b56bf9 is described below

commit 3dcae5b56bf92af7d35aaeb263e8ef959724c8e2
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Sep 28 11:58:05 2026 +0200

    CAMEL-25074: camel-sql - say in the outputType description that a 
StreamList body is an Iterator with no size
    
    outputType=StreamList makes the body a ResultSetIterator. The description 
said
    the result is streamed "using an Iterator" and "can be used with the 
Splitter
    EIP in streaming mode", which is accurate but stops one sentence short of 
the
    consequence: the body has no size and can be read only once. Treating it as 
a
    list then fails with an error that does not mention the option that caused 
it:
    
      MethodNotFoundException: Method with name: size() not found on bean:
      org.apache.camel.component.sql.ResultSetIterator@1bdc4d7c
    
    Measured while benchmarking a local model on a step that selects rows, logs
    ${body.size()} and splits the list, 30 times over three runs: SelectList 
and no
    outputType worked, StreamList failed 8 times out of 8, always on size(). It
    reads that the result is an Iterator for the Splitter, chooses it, and 
sizes the
    body anyway.
    
    Closes #26965
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 .../org/apache/camel/catalog/components/sql.json   |  2 +-
 .../org/apache/camel/component/sql/sql.json        |  2 +-
 .../camel/component/sql/DefaultSqlEndpoint.java    |  4 ++-
 .../endpoint/dsl/SqlEndpointBuilderFactory.java    | 30 +++++++++++++++++-----
 4 files changed, 29 insertions(+), 9 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
index fca8d9d34bd1..6386c9f71bc3 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql.json
@@ -54,7 +54,7 @@
     "dataSource": { "index": 2, "kind": "parameter", "displayName": "Data 
Source", "group": "common", "label": "", "required": false, "type": "object", 
"javaType": "javax.sql.DataSource", "deprecated": false, "deprecationNote": "", 
"autowired": true, "secret": false, "description": "Sets the DataSource to use 
to communicate with the database at endpoint level." },
     "outputClass": { "index": 3, "kind": "parameter", "displayName": "Output 
Class", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Specify the full package and class name to use 
as conversion when outputType=SelectOne." },
     "outputHeader": { "index": 4, "kind": "parameter", "displayName": "Output 
Header", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Store the query result in a header instead of 
the message body. By default, outputHeader == null and the query result is 
stored in the message body, any existing content in the message body is 
discarded. If outputHeader is set, th [...]
-    "outputType": { "index": 5, "kind": "parameter", "displayName": "Output 
Type", "group": "common", "label": "", "required": false, "type": "enum", 
"javaType": "org.apache.camel.component.sql.SqlOutputType", "enum": [ 
"SelectOne", "SelectList", "StreamList" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "SelectList", "description": "Make the 
output of consumer or producer to SelectList as List of Map, or SelectOne as 
single Java object in the following way [...]
+    "outputType": { "index": 5, "kind": "parameter", "displayName": "Output 
Type", "group": "common", "label": "", "required": false, "type": "enum", 
"javaType": "org.apache.camel.component.sql.SqlOutputType", "enum": [ 
"SelectOne", "SelectList", "StreamList" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "SelectList", "description": "Make the 
output of consumer or producer to SelectList as List of Map, or SelectOne as 
single Java object in the following way [...]
     "separator": { "index": 6, "kind": "parameter", "displayName": 
"Separator", "group": "common", "label": "", "required": false, "type": 
"string", "javaType": "char", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": ",", "description": "The separator to use when 
parameter values is taken from message body (if the body is a String type), to 
be inserted at # placeholders. Notice if you use named parameters, then a Map 
type is used instead. The default value is comma" },
     "breakBatchOnConsumeFail": { "index": 7, "kind": "parameter", 
"displayName": "Break Batch On Consume Fail", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "Sets whether to break batch if onConsume failed." },
     "expectedUpdateCount": { "index": 8, "kind": "parameter", "displayName": 
"Expected Update Count", "group": "consumer", "label": "consumer", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": -1, "description": "Sets an expected 
update count to validate when using onConsume." },
diff --git 
a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json
 
b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json
index fca8d9d34bd1..6386c9f71bc3 100644
--- 
a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json
+++ 
b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/sql.json
@@ -54,7 +54,7 @@
     "dataSource": { "index": 2, "kind": "parameter", "displayName": "Data 
Source", "group": "common", "label": "", "required": false, "type": "object", 
"javaType": "javax.sql.DataSource", "deprecated": false, "deprecationNote": "", 
"autowired": true, "secret": false, "description": "Sets the DataSource to use 
to communicate with the database at endpoint level." },
     "outputClass": { "index": 3, "kind": "parameter", "displayName": "Output 
Class", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Specify the full package and class name to use 
as conversion when outputType=SelectOne." },
     "outputHeader": { "index": 4, "kind": "parameter", "displayName": "Output 
Header", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Store the query result in a header instead of 
the message body. By default, outputHeader == null and the query result is 
stored in the message body, any existing content in the message body is 
discarded. If outputHeader is set, th [...]
-    "outputType": { "index": 5, "kind": "parameter", "displayName": "Output 
Type", "group": "common", "label": "", "required": false, "type": "enum", 
"javaType": "org.apache.camel.component.sql.SqlOutputType", "enum": [ 
"SelectOne", "SelectList", "StreamList" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "SelectList", "description": "Make the 
output of consumer or producer to SelectList as List of Map, or SelectOne as 
single Java object in the following way [...]
+    "outputType": { "index": 5, "kind": "parameter", "displayName": "Output 
Type", "group": "common", "label": "", "required": false, "type": "enum", 
"javaType": "org.apache.camel.component.sql.SqlOutputType", "enum": [ 
"SelectOne", "SelectList", "StreamList" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "SelectList", "description": "Make the 
output of consumer or producer to SelectList as List of Map, or SelectOne as 
single Java object in the following way [...]
     "separator": { "index": 6, "kind": "parameter", "displayName": 
"Separator", "group": "common", "label": "", "required": false, "type": 
"string", "javaType": "char", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": ",", "description": "The separator to use when 
parameter values is taken from message body (if the body is a String type), to 
be inserted at # placeholders. Notice if you use named parameters, then a Map 
type is used instead. The default value is comma" },
     "breakBatchOnConsumeFail": { "index": 7, "kind": "parameter", 
"displayName": "Break Batch On Consume Fail", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "Sets whether to break batch if onConsume failed." },
     "expectedUpdateCount": { "index": 8, "kind": "parameter", "displayName": 
"Expected Update Count", "group": "consumer", "label": "consumer", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": -1, "description": "Sets an expected 
update count to validate when using onConsume." },
diff --git 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
index f808ab51ccef..68e9d19576bc 100644
--- 
a/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
+++ 
b/components/camel-sql/src/main/java/org/apache/camel/component/sql/DefaultSqlEndpoint.java
@@ -114,7 +114,9 @@ public abstract class DefaultSqlEndpoint extends 
DefaultPollingEndpoint implemen
                             + " c) If the outputClass is set, then it will 
convert the query result into an Java bean object by calling all the setters 
that match the column names."
                             + " It will assume your class has a default 
constructor to create instance with."
                             + " d) If the query resulted in more than one 
rows, it throws an non-unique result exception."
-                            + " StreamList streams the result of the query 
using an Iterator. This can be used with the Splitter EIP in streaming mode to 
process the ResultSet in streaming fashion.")
+                            + " StreamList streams the result of the query 
using an Iterator. This can be used with the Splitter EIP in streaming mode to 
process the ResultSet in streaming fashion."
+                            + " The body is then a ResultSetIterator and not a 
List: it has no size, and it can only be read once, so split it to work on the 
rows"
+                            + " instead of calling size() or indexing it. Use 
SelectList when the whole result is wanted as a List of Map.")
     private SqlOutputType outputType = SqlOutputType.SelectList;
     @UriParam(description = "Specify the full package and class name to use as 
conversion when outputType=SelectOne.")
     private String outputClass;
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
index 29c523e3706d..848f3d681a93 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SqlEndpointBuilderFactory.java
@@ -150,7 +150,10 @@ public interface SqlEndpointBuilderFactory {
          * in more than one rows, it throws an non-unique result exception.
          * StreamList streams the result of the query using an Iterator. This
          * can be used with the Splitter EIP in streaming mode to process the
-         * ResultSet in streaming fashion.
+         * ResultSet in streaming fashion. The body is then a ResultSetIterator
+         * and not a List: it has no size, and it can only be read once, so
+         * split it to work on the rows instead of calling size() or indexing
+         * it. Use SelectList when the whole result is wanted as a List of Map.
          * 
          * The option is a:
          * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
@@ -178,7 +181,10 @@ public interface SqlEndpointBuilderFactory {
          * in more than one rows, it throws an non-unique result exception.
          * StreamList streams the result of the query using an Iterator. This
          * can be used with the Splitter EIP in streaming mode to process the
-         * ResultSet in streaming fashion.
+         * ResultSet in streaming fashion. The body is then a ResultSetIterator
+         * and not a List: it has no size, and it can only be read once, so
+         * split it to work on the rows instead of calling size() or indexing
+         * it. Use SelectList when the whole result is wanted as a List of Map.
          * 
          * The option will be converted to a
          * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
@@ -1538,7 +1544,10 @@ public interface SqlEndpointBuilderFactory {
          * in more than one rows, it throws an non-unique result exception.
          * StreamList streams the result of the query using an Iterator. This
          * can be used with the Splitter EIP in streaming mode to process the
-         * ResultSet in streaming fashion.
+         * ResultSet in streaming fashion. The body is then a ResultSetIterator
+         * and not a List: it has no size, and it can only be read once, so
+         * split it to work on the rows instead of calling size() or indexing
+         * it. Use SelectList when the whole result is wanted as a List of Map.
          * 
          * The option is a:
          * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
@@ -1566,7 +1575,10 @@ public interface SqlEndpointBuilderFactory {
          * in more than one rows, it throws an non-unique result exception.
          * StreamList streams the result of the query using an Iterator. This
          * can be used with the Splitter EIP in streaming mode to process the
-         * ResultSet in streaming fashion.
+         * ResultSet in streaming fashion. The body is then a ResultSetIterator
+         * and not a List: it has no size, and it can only be read once, so
+         * split it to work on the rows instead of calling size() or indexing
+         * it. Use SelectList when the whole result is wanted as a List of Map.
          * 
          * The option will be converted to a
          * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
@@ -2229,7 +2241,10 @@ public interface SqlEndpointBuilderFactory {
          * in more than one rows, it throws an non-unique result exception.
          * StreamList streams the result of the query using an Iterator. This
          * can be used with the Splitter EIP in streaming mode to process the
-         * ResultSet in streaming fashion.
+         * ResultSet in streaming fashion. The body is then a ResultSetIterator
+         * and not a List: it has no size, and it can only be read once, so
+         * split it to work on the rows instead of calling size() or indexing
+         * it. Use SelectList when the whole result is wanted as a List of Map.
          * 
          * The option is a:
          * <code>org.apache.camel.component.sql.SqlOutputType</code> type.
@@ -2257,7 +2272,10 @@ public interface SqlEndpointBuilderFactory {
          * in more than one rows, it throws an non-unique result exception.
          * StreamList streams the result of the query using an Iterator. This
          * can be used with the Splitter EIP in streaming mode to process the
-         * ResultSet in streaming fashion.
+         * ResultSet in streaming fashion. The body is then a ResultSetIterator
+         * and not a List: it has no size, and it can only be read once, so
+         * split it to work on the rows instead of calling size() or indexing
+         * it. Use SelectList when the whole result is wanted as a List of Map.
          * 
          * The option will be converted to a
          * <code>org.apache.camel.component.sql.SqlOutputType</code> type.

Reply via email to