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]

Reply via email to