Mybatis error of Could not find result map java.util.List

1. Reproduce the error

Error prompt:

13:41:33.539 ERROR com.fast.framework.advice.FastBootControllerAdvice 58 errorHandler - Could not find result map java.util.List org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.util.List
	at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:346) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:290) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.builder.xml.XMLStatementBuilder.parseStatementNode(XMLStatementBuilder.java:109) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.session.Configuration.lambda$buildAllStatements$2(Configuration.java:787) ~[mybatis-3.5.0.jar:3.5.0]
	at java.util.Collection.removeIf(Collection.java:414) ~[?:1.8.0_112]
	at org.apache.ibatis.session.Configuration.buildAllStatements(Configuration.java:786) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:763) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.session.Configuration.hasStatement(Configuration.java:758) ~[mybatis-3.5.0.jar:3.5.0]
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod$SqlCommand.resolveMappedStatement(MybatisMapperMethod.java:264) ~[mybatis-plus-core-3.1.0

2. Background

First of all, go to the official website to confirm that the usage of resultMap and resultType is correct. This article does not discuss basic usage, so for errors after using myabtis proficiently

Official website: http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#select

3. Recover the scene

(1) Dao layer has two methods, remember that these two fast are normal, and the test is wrong

int selectFast();

int selectTest();

(2) Corresponding to xml, where selectTest is problematic, resultMap="java.util.List" is wrong to write

<select id="selectFast" resultType="java.lang.Integer">
    select count(1) from sys_user
</select>

<select id="selectTest" resultMap="java.util.List">
    select count(1) from sys_user
</select>

(3) Then I only call the normal method int selectFast();

masterDao.selectFast()

(4) Normal maven clean, install and package are all normal

(5) After compiling and starting, it also starts normally

(6) Then when the normal method selectFast is called through the controller, the initial error is reported

Could not find result map java.util.List

(7) Similar to this error, there will be a hint where the error occurred. The hint of this error is:

at com.fast.web.controller.TestController.getString(TestController.java:25) ~[classes/:?]

This is the 25th line of this TestController, I also called this method, it is reasonable to say

(8) But what is the incorrect problem?

The method int selectFast(); I am currently calling is normal. There is no problem with the code, and the calling interface is only this method, so the code should execute normally.

But mybatis returned an error, returning a method (int selectTest();) that was irrelevant to the interface call at the time. However, this error did not report an error during the compilation phase and the startup phase. When calling other methods, the error of this method is prompted, and the position of the error is the position of the correct method.

Idea : Solve the problem first, then clarify the problem, directly correct the error of the irrelevant method, modify as follows, the int selectTest(); method is normal, and the prompt of re-access is normal.

<select id="selectTest" resultType="java.lang.Integer">
    select count(1) from sys_user
</select>

The solution at the time was debug : Because of the normal method I requested, the return parameter should be resultType, but where did this resultMap come from, and it also reported an error. Look at the location of the error message displayed by mybatis.

14:04:46.787 ERROR com.fast.framework.advice.FastBootControllerAdvice 58 errorHandler - Could not find result map java.util.List org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.util.List
	at org.apache.ibatis.builder.MapperBuilderAssistant.getStatementResultMaps(MapperBuilderAssistant.java:346) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.builder.MapperBuilderAssistant.addMappedStatement(MapperBuilderAssistant.java:290) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.builder.xml.XMLStatementBuilder.parseStatementNode(XMLStatementBuilder.java:109) ~[mybatis-3.5.0.jar:3.5.0]
	at org.apache.ibatis.session.Configuration.lambda$buildAllStatements$2(Configuration.java:787) ~[mybatis-3.5.0.jar:3.5.0]
	at java.util.Collection.removeIf(Collection.java:414) ~[?:1.8.0_112]

Find this (XMLStatementBuilder.java:109) and make a breakpoint. Below is the mybatis source code, and the breakpoint is on the last line.

Re-request, see the resultMap parameters sent over

 public void parseStatementNode() {
        String id = this.context.getStringAttribute("id");
        String databaseId = this.context.getStringAttribute("databaseId");
        if (this.databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
            Integer fetchSize = this.context.getIntAttribute("fetchSize");
            Integer timeout = this.context.getIntAttribute("timeout");
            String parameterMap = this.context.getStringAttribute("parameterMap");
            String parameterType = this.context.getStringAttribute("parameterType");
            Class<?> parameterTypeClass = this.resolveClass(parameterType);
            String resultMap = this.context.getStringAttribute("resultMap");
            String resultType = this.context.getStringAttribute("resultType");
            String lang = this.context.getStringAttribute("lang");
            LanguageDriver langDriver = this.getLanguageDriver(lang);
            Class<?> resultTypeClass = this.resolveClass(resultType);
            String resultSetType = this.context.getStringAttribute("resultSetType");
            StatementType statementType = StatementType.valueOf(this.context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
            ResultSetType resultSetTypeEnum = this.resolveResultSetType(resultSetType);
            String nodeName = this.context.getNode().getNodeName();
            SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
            boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
            boolean flushCache = this.context.getBooleanAttribute("flushCache", !isSelect);
            boolean useCache = this.context.getBooleanAttribute("useCache", isSelect);
            boolean resultOrdered = this.context.getBooleanAttribute("resultOrdered", false);
            XMLIncludeTransformer includeParser = new XMLIncludeTransformer(this.configuration, this.builderAssistant);
            includeParser.applyIncludes(this.context.getNode());
            this.processSelectKeyNodes(id, parameterTypeClass, langDriver);
            SqlSource sqlSource = langDriver.createSqlSource(this.configuration, this.context, parameterTypeClass);
            String resultSets = this.context.getStringAttribute("resultSets");
            String keyProperty = this.context.getStringAttribute("keyProperty");
            String keyColumn = this.context.getStringAttribute("keyColumn");
            String keyStatementId = id + "!selectKey";
            keyStatementId = this.builderAssistant.applyCurrentNamespace(keyStatementId, true);
            Object keyGenerator;
            if (this.configuration.hasKeyGenerator(keyStatementId)) {
                keyGenerator = this.configuration.getKeyGenerator(keyStatementId);
            } else {
                keyGenerator = this.context.getBooleanAttribute("useGeneratedKeys", this.configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType)) ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
            }

            this.builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, (KeyGenerator)keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
        }
    }

Then check the debug parameters, my interface request is selectFast(), a normal method, but now I also checked selectTest(); this problematic method.

resultMap returns java.util.List

So search the selectTest method globally, modify the return parameters, and complete the bug fix.

Summary : This bug is not a complicated bug, nor a meaningful bug, but mybatis compiles and starts without reporting an error. When a normal interface is requested, an error of an irrelevant method is reported. This prompt location is problematic. , It will cause you to waste a lot of time in troubleshooting. First remember that there will be this problem, and you will avoid a pit in the future.

 

Guess you like

Origin blog.csdn.net/Mint6/article/details/98330873