MyBatis version

3.5.4

Problem

https://www.javadoc.io/doc/org.mybatis/mybatis/latest/org/apache/ibatis/cursor/Cursor.html The javadoc of Cursor has the following constraint:

If you use collections in resultMaps then cursor SQL queries must be ordered (resultOrdered="true") using the id columns of the resultMap.

However, there is no validation during query execution, which may result in uncertain outcomes. And it is not clearly stated in the documentation neither.

Test case or example project

Added in CursorNestedTest in this PR.

Steps to reproduce

  1. Create a database with unordered data.
  2. Execute nested resultMap cursor queries and iterate the cursor with ordered/unordered SQL queries and resultOrdered true/false. See results below.

Actual result

See CursorNestedTest in eb4fe9aa73a8b6660f9fa699b0c773704a34d158 for the results

Case SQL query ordered? resultOrdered? Outcome
1 Y Y Correct(and memory efficient)
2 Y N May have missing elements in collection during iteration, but execution appears to have no error.
3 N Y New rows of an already mapped ID becomes new elements in the cursor due to the wrong resultOrdered assumption. Hard to check but it is caller's fault.
4 N N Seems to be correct given that memory is enough, but it violates Cursor javadoc anyway.

Expected result

  • MyBatis should inform callers about the constraint violation in case 2 and 4 mentioned in Cursor's javadoc rather than producing uncertain result.
  • The mentioned constraint should also be stated in documentation.

Fix

  • BaseExecutor#queryCursor throws ExecutorException if MappedStatement has nested result maps but is not result ordered
  • It may be controversial that this may be a breaking change because existing users having implementation similar to case 2 and 4 will crash something after the fix. But it is preferred to give users an error rather than a result which may be false positive. (For my case, I misused it without being noticed, and brought it to production code for a days...But luckily the impact was just minor.) Comments are welcome if a non-breaking alternative is preferred or suggested.
  • Update English and Japanese documentation regarding to resultOrdered configuration
  • Sorry that I don't know all languages

Comment From: ericlai616

Is there any problem in Travis CI? My local build didn't have any problem.

And sorry, it seems that nested result map with association only may also throw exception due to this change. Is there a way to distinguish whether the nested result maps contain association or collection?

Comment From: ericlai616

Sorry for incomplete PR. I think I have found a way to perform the validation but I need some more time. I'll separate the documentation update and query validation in separate PRs.