Fix issue: Use auditStrategy to cause duplicate generation keyGenerator #35223
+17
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 hasgeneratedKeyContext
inner it.But it'll re-generate the key and add to the
generatedKeyContext#generatedValues
again, because it also execute thecreateShardingConditions
method, see lines 75 and 177.shardingsphere/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java
Lines 71 to 77 in 3bd8866
shardingsphere/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngine.java
Lines 170 to 183 in 3bd8866
Actually, when an
Insert
sql be executed, and configured to use the generated key, thegeneratedKeyContext#generatedValues().size()
will besqlStatementContext.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 ofrs
anditerator
to match, or it'll throwExecutorException
.https://github.com/mybatis/mybatis-3/blob/5f8927deebb846b299a99baba984b7db5400b312/src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java#L119-L125
In the above example, the number of
rs
elements (2) is one more than theiterator
, which causes the exception.My solution is to store a copy of getGeneratedValues() named
savedGeneratedValues
beforeShardingSpherePreconditions.checkNotEmpty()
, and after that, reassigngetGeneratedValues()
in the finally block to thesavedGeneratedValues
.Before committing this PR, I'm sure that I have checked the following options:
./mvnw clean install -B -T1C -Dmaven.javadoc.skip -Dmaven.jacoco.skip -e
.