Reputation: 2801
Hello StackOverflowers,
There is something I don't get about MyBatis resultMap.
The model I'm working on is beeing updated. We decided to create a new graph of objects which reflects our future DB schema (the current one is awful).
To sum up our problem, here is a simple case:
The current Object whith is related to table SITE is org.example.model.SiteModel
. We created a new Object called org.example.entity.Site
. (The package name is temporary).
The goal is now to use the existing SQL request developed thank to MyBatis and add a new ResultMap linked to the return type of our method.
Here is a an example:
/**
* Get all site defined as template.
*/
@Select("SELECT * FROM SITE WHERE ISTEMPLATE = 'True'")
@ResultMap({"siteResMap" , "siteResultMap"})
@Options(statementType = StatementType.CALLABLE)
<T> List<T> findTemplates();
Then, in an XML configuration file, we defined the following mappings:
...
<resultMap id="siteResMap" type="org.example.entity.Site" />
<resultMap id="siteResultMap" type="org.example.model.SiteModel" />
...
And then we call the method from our DAO:
List<Site> site = siteDao.findTemplates();
List<SiteModel> siteMod = siteDao.findTemplates();
What we are expecting from this is a dynamic interpretation from MyBatis, taking the right ResultMap according to the computed return type.
But both list are shown as List<org.example.entity.Site>
from debuger.
It makes me think that the first ResultMap is taken, ignoring the second one.
Am I missing something ? Is there a way to make MyBatis behave in such way ?
Regards
Upvotes: 3
Views: 1815
Reputation: 2801
After a lot a research and code exploration, we found out that the String[]
of ResultMap is not designed to link java return types to the resultMap.
This is function retrieving the resultmap (from org.apache.ibatis.executor.resultset.DefaultResultSetHandler
)
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
final List<Object> multipleResults = new ArrayList<Object>();
int resultSetCount = 0;
ResultSetWrapper rsw = getFirstResultSet(stmt);
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
validateResultMapsCount(rsw, resultMapCount);
while (rsw != null && resultMapCount > resultSetCount) {
ResultMap resultMap = resultMaps.get(resultSetCount);
handleResultSet(rsw, resultMap, multipleResults, null);
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
String[] resultSets = mappedStatement.getResulSets();
if (resultSets != null) {
while (rsw != null && resultSetCount < resultSets.length) {
ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
if (parentMapping != null) {
String nestedResultMapId = parentMapping.getNestedResultMapId();
ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
handleResultSet(rsw, resultMap, null, parentMapping);
}
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
}
return collapseSingleResultList(multipleResults);
}
It explains why we always got a List of elements of type of the first resultMap.
We created a new Dao to map new object types.
Upvotes: 1