Iceberry-qdd opened a new pull request, #35223:
URL: https://github.com/apache/shardingsphere/pull/35223

   Fixes #22719 .
   
   Changes proposed in this pull request:
     - This component only determines whether a DML sql take the sharding keys. 
So it shouldn't change the `sqlStatementContext` object, the object has 
`generatedKeyContext` inner it.
     - But it'll re-generate the key and add to the 
`generatedKeyContext#generatedValues` again, because it also execute the 
`createShardingConditions` method, see lines 75 and 177.
     
https://github.com/apache/shardingsphere/blob/3bd8866054bfcbe4f76e20c54d00147ee64036a1/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java#L71-L77
   
https://github.com/apache/shardingsphere/blob/3bd8866054bfcbe4f76e20c54d00147ee64036a1/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java#L170-L183
   
   - Actually, when an `Insert` sql be executed, and configured to use the 
generated key, the `generatedKeyContext#generatedValues().size()` will be 
`sqlStatementContext.getValueListCount() * 2` finally, the generatedKeys 
actually inserted to the db is generated by audit process, origin process also 
generated the keys, but they'll be ignored, this can be acceptable.
   - For `mybatis` or other frameworks(may be), it can bring out the key from 
the generated keys and assign it to the entity, but it requires the element 
count of `rs` and `iterator` to match, or it'll throw `ExecutorException`.
     
https://github.com/mybatis/mybatis-3/blob/5f8927deebb846b299a99baba984b7db5400b312/src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java#L119-L125
   
   ```xml
   mapper.xml
   <insert id="insert" parameterType="com.iceberry.Order" keyColumn="id" 
useGeneratedKeys="true" keyProperty="id">
       INSERT INTO tb_order (user_id, product_id, amount, count, created_time)
           VALUES (
               #{userId},
               #{productId},
               #{amount},
               #{count},
               #{createdTime}
           )
   </insert>
   ```
   
   ```java
   void test_insert(Long userId, Long productId, Long count, BigDecimal amount, 
LocalDateTime createdTime) {
       Order order = new Order(null, userId, productId, count, amount, 
createdTime);
       int rows = mapper.insert(order);
       System.out.println(order.getId()); // will be the key generated by 
shardingSphere
       Assertions.assertEquals(1, rows);
       Assertions.assertNotNull(order.getId());
   }
   ```
   
   
![image](https://github.com/user-attachments/assets/8b266225-e651-4740-b2ba-465a55ced42b)
   
![image](https://github.com/user-attachments/assets/75e3b1eb-f3e9-41c2-bcfc-6efed9979e6e)
   
   In the above example, the number of `rs` elements (2) is one more than the 
`iterator`, which causes the exception.
   
   My solution is to store a copy of getGeneratedValues() named 
`savedGeneratedValues` before `ShardingSpherePreconditions.checkNotEmpty()`, 
and after that, reassign `getGeneratedValues()` in the finally block to the 
`savedGeneratedValues`.
   
   ---
   
   Before committing this PR, I'm sure that I have checked the following 
options:
   - [ ] My code follows the [code of 
conduct](https://shardingsphere.apache.org/community/en/involved/conduct/code/) 
of this project.
   - [ ] I have self-reviewed the commit code.
   - [ ] I have (or in comment I request) added corresponding labels for the 
pull request.
   - [ ] I have passed maven check locally : `./mvnw clean install -B -T1C 
-Dmaven.javadoc.skip -Dmaven.jacoco.skip -e`.
   - [ ] I have made corresponding changes to the documentation.
   - [ ] I have added corresponding unit tests for my changes.
   - [ ] I have updated the Release Notes of the current development version. 
For more details, see [Update Release 
Note](https://shardingsphere.apache.org/community/en/involved/contribute/contributor/)
   


-- 
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: notifications-unsubscr...@shardingsphere.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to