mybatis-3: record missing in result
MyBatis version
3.5.4
Database vendor and version
H2
Test case or example project
https://github.com/blindpirate/mybatis-bug-reproduction
Steps to reproduce
mvn flyway:migrate- Run
Mainclass:
The result set should be 3 rows, but MyBatis returns 2 rows.
Expected result
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 240166646.
DEBUG [main] - Setting autocommit to false on JDBC Connection [conn0: url=jdbc:h2:file:./target/test user=ROOT]
DEBUG [main] - ==> Preparing: select USER.id,USER.name,t.score_num from (select USER_ID,sum(SCORE) as score_num from `MATCH` group by USER_ID) t inner join USER on t.USER_ID=USER.ID
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
Result size: 3
Actual result
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 240166646.
DEBUG [main] - Setting autocommit to false on JDBC Connection [conn0: url=jdbc:h2:file:./target/test user=ROOT]
DEBUG [main] - ==> Preparing: select USER.id,USER.name,t.score_num from (select USER_ID,sum(SCORE) as score_num from `MATCH` group by USER_ID) t inner join USER on t.USER_ID=USER.ID
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
Result size: 2
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 18 (13 by maintainers)
Commits related to this issue
- Test case for issue #1848 — committed to mybatis/mybatis-3 by emacarron 4 years ago
- Fix for issue #1848 — committed to mybatis/mybatis-3 by emacarron 4 years ago
- Restored two missing tests #1848 — committed to mybatis/mybatis-3 by emacarron 4 years ago
The behavior reported in this issue does not seem like a bug to me.
@Huangxuny1 ,
When using
<collection />or<association />, it is very important to understand how MyBatis identifies the parent object.Here is your result map:
As there is no
<id />in the root level, MyBatis usesscore_numas the ID of the root object (=RankItem) and associatesUserfor eachRankItem[1]. The example query result is:As I explained,
score_numis the ID ofRankItem, so there will be twoRankItems (score=1300 and score=500) instead of 3. This is how it happens.Now, assuming you actually want one
RankItemfor eachUser, you need to tell MyBatis to use the column that identifiesUSER(i.eUSER.id) to identifyRankItem. To do this, you just need to add<id />to your result map.It’s pretty much the same with
<collection />.Notes:
propertyin the<id />element as there is no corresponding property inRankItem.<id />in<collection />or<association />as well (i.e.<id property="id" column="id"/>). It helps MyBatis work more efficiently and is mandatory in advanced (=complex) mappings. This is mentioned in the doc.Please try it and let us know if there is any further questions.
[1] When there is no
<id />element, MyBatis uses the combination of all<result />elements as the ID.@emacarron , @h3adache I am not so sure, but I think that the line 1054 is for a result map that has
<constructor />in it. I’ll take a deeper look once I find some more time.Thank you both!
@emacarron
I read the code and agree with you on your following statement.
It might break existing code, but it should be possible to fix the breakage by specifying property-less-id elements as I explained above.
OK, thanks
On Thu, Mar 12, 2020 at 11:40 PM Iwao AVE! notifications@github.com wrote: