davsclaus commented on code in PR #27641:
URL: https://github.com/apache/camel/pull/27641#discussion_r4236604393
##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc:
##########
@@ -826,6 +826,14 @@ and most services, which were not registered at this level
already). Prior to Ca
every component. Use `RoutesOnly` (or `Default`) to keep the component MBeans.
The CamelContext, health check and route
controller MBeans are still registered.
+=== camel-mybatis - a String body is one parameter (Breaking change)
+
+With `statementType=Insert`, `Update` or `Delete`, a `String` body (or input
header) is now passed to the statement as
+one parameter, also when it contains commas or is blank, and so is an array of
a primitive type such as a `byte[]`.
Review Comment:
If the array handling stays as it is, this should also mention `int[]`,
`long[]` etc. Those used to run the statement once per element, and that is the
case a user is most likely to rely on (an array of ids). It should also say
that MyBatis receives an array wrapped as a parameter map, so the statement has
to refer to it as `#{array}`. If it is narrowed to `byte[]`, just update the
wording to match.
##########
components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisProducer.java:
##########
@@ -297,6 +279,19 @@ public MyBatisEndpoint getEndpoint() {
return (MyBatisEndpoint) super.getEndpoint();
}
+ /**
+ * Iterates a collection, an iterator, a stream or an array of objects, to
run the statement once per element. Any
+ * other value is one parameter as-is: a Map, a String (which may contain
commas) and a primitive array (such as a
+ * byte[]).
+ */
+ private static Iterator<?> createIterator(Object in) {
+ if (in instanceof Map || in instanceof String
+ || (in.getClass().isArray() &&
in.getClass().getComponentType().isPrimitive())) {
Review Comment:
Should this cover every primitive array, or only `byte[]`?
For `int[]`/`long[]` the old behaviour was useful. Each element is boxed
into an `Integer`/`Long`, which has a MyBatis type handler, so `delete ...
where ACC_ID = #{id}` with a `long[]` body deleted every id. With this change
the whole array goes to `session.delete(statement, array)`, and MyBatis'
`DefaultSqlSession.wrapCollection` (`ParamNameResolver.wrapToMapIfCollection`)
wraps any array into a `ParamMap` with only the key `array`. The same statement
then fails with `BindingException: Parameter 'id' not found. Available
parameters are [array]`. Running a statement once with the whole array is what
`DeleteList`/`InsertList`/`UpdateList` are for.
`byte[]` is the one case where per-element made no sense (one row per byte).
So I would narrow it, and add a small test for the `byte[]` case. Note that the
statement has to refer to it as `#{array}` because of the wrapping above:
```suggestion
if (in instanceof Map || in instanceof String || in instanceof
byte[]) {
```
(The javadoc above would need the same change.)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]