shashank created CAMEL-25508:
--------------------------------
Summary: camel-mybatis - a String body with a comma runs Insert,
Update and Delete once per comma-separated part
Key: CAMEL-25508
URL: https://issues.apache.org/jira/browse/CAMEL-25508
Project: Camel
Issue Type: Bug
Components: camel-mybatis
Reporter: shashank
{{MyBatisProducer}} runs {{statementType=Insert}}, {{Update}} and {{Delete}}
once per element of {{ObjectHelper.createIterator(body)}} (lines 126-148,
165-187 and 204-226 at main c578a42a776d), with only a {{Map}} body passed
as-is (CAMEL-18321). Besides collections, iterators and object arrays,
{{createIterator}} splits a {{String}} at every comma (default delimiter), and
iterates a primitive array element by element. So a statement with a String
parameter runs once per comma-separated part, with the parts as parameters:
* inserting the last name {{"Doe, Jr."}} inserts two rows, {{"Doe"}} and {{"
Jr."}};
* an update to {{"Strachan, Jr."}} runs twice and leaves {{" Jr."}};
* deleting by the value {{"Ibsen, Strachan"}} deletes the rows whose value is
{{"Ibsen"}} and the rows whose value is {{" Strachan"}};
* a {{byte[]}} parameter runs the statement once per byte, and a blank String
does not run it at all.
The same applies to the {{inputHeader}} option. The documentation describes the
body as the parameter of the statement ("send an {{Account}} object as the IN
body", "the IN body should contain the account id"); the comma splitting is not
documented anywhere.
h3. Reproduction
New {{MyBatisStringParameterTest}} (embedded database of the module, three
String-parameter statements added to the test {{Account.xml}}). On main all
four fail:
{noformat}
testInsertStringWithComma: There should be 3 rows ==> expected: <3> but was: <4>
testUpdateStringWithComma: expected: <Strachan, Jr.> but was: < Jr.>
testDeleteStringWithComma: There should be 1 row ==> expected: <1> but was: <0>
testInsertBlankString: There should be 3 rows ==> expected: <3> but was: <2>
{noformat}
h3. Proposed fix
A small helper in {{MyBatisProducer}} passes a {{Map}}, a {{String}} and a
primitive array as one parameter, and iterates everything else as before
(collections, iterators, streams, object arrays still run the statement once
per element; the module's test setup inserts an {{Account[]}}). Upgrade guide
note for 4.23, marked as a breaking change for anyone who relied on the
splitting (for example a body {{"1,2,3"}} to delete three ids): a String with
commas, a blank String and a {{byte[]}} are now one parameter; send a {{List}}
to run the statement once per value. camel-mybatis tests with the fix: 44, 0
failures.
Found with a Lean 4 model of the three statement types and {{createIterator}}
(comma splitting as in {{StringHelper.splitOnCharacterAsIterator}}): the
property "a value that is not a collection reaches the statement as one
parameter" fails for {{"Doe, Jr."}}, and is proved to fail for every String
with an inner comma (the number of statements is the number of commas plus
one). The fix is proved to satisfy it for every body, and to equal main for
every body that is not a String or a primitive array. Then confirmed with the
real component as above.
Affected: main, camel-4.18.x, camel-4.14.x (same code, GitHub contents API).
The iteration dates from the first version of the component (2011), whose
comment reads "lets handle arrays or collections of objects"; CAMEL-5143
(InsertList) and CAMEL-18321 (Map as-is) discuss lists and maps only. The
String splitting is not mentioned in the docs, tests or tickets.
Duplicate check (2026-10-09): JIRA text "mybatis" with
"comma"/"createIterator"/"String body" (6 hits, none about this: CAMEL-5143
InsertList, others unrelated), component camel-mybatis created in the last 4
years (3, docs and autowiring); GitHub pull requests "mybatis comma",
"MyBatisProducer", "mybatis String body": none.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)