Throw exception in DefaultResultSetHandler when more result set got returned than was expected
See original GitHub issueHi,
We are in the works of migrating JTDS to MSSQL JDBC and there is some different behavior in these.
For example when someone adds an extra SELECT-statement in a procedure we receive this from mybatis + jtds when doing a select-mapping.
Error attempting to get column #1 from callable statement. Cause: java.sql.SQLException: Output parameters have not yet been processed. Call getMoreResults().
However when using MSSQL JDBC we don’t get any exception at all but instead mybatis processes the resultset it gets back with weird results.
I was debugging the code a bit and I think there should be an exception thrown in DefaultResultSetHandler
when we get more resultsets back than expected, here:
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
final List<Object> multipleResults = new ArrayList<>();
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++;
}
// PATCH
// Here rsw should be null else we got more result sets than what's specified in the mappings
if (rsw != null)
{
throw new RuntimeException("Received a resultset when no more resultset's was expected");
}
String[] resultSets = mappedStatement.getResultSets();
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);
}
Issue Analytics
- State:
- Created a year ago
- Comments:9 (4 by maintainers)
Top Results From Across the Web
ResultSet exception - before start of result set - Stack Overflow
Basically you are positioning the cursor before the first row and then requesting data. You need to move the cursor to the first...
Read more >Retrieving and Modifying Values from Result Sets (The Java ...
A ResultSet object is a table of data representing a database result set, ... When a getter method is called with a string...
Read more >12. Data access with JDBC - Spring
Exceptions thrown during JDBC processing are translated to exceptions defined in ... iteration over ResultSet s and extraction of returned parameter values.
Read more >[JAVA-2176] Common Functional Read API for ResultSet and ...
I have been attempting to port my applications from the 3.x driver to 4.0 rc1. Some of what has been difficult will be...
Read more >DefaultCursor.java - MyBatis.org
This is the default implementation of a MyBatis Cursor. ... throw new IllegalStateException("Cannot open more than one iterator on a Cursor");
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Ok thanks anyways. I did however solve this with an interceptor to mybatis so we go for that instead 😃
Hi,
I’ve changed the test-case a bit to make it more clear about our problem, I’ll also give you a bit background about how we work with SQL at our place to get you a better picture about this problem.
So at our place we work with SQL in a quite different way than most people do, we have insane amount of SQL and stored procedures which handles complex logic and flows, some procedures in the 1000’s of lines and calls nested procedures etc. There are developers that only develop SQL flows with our procedures and one tool that is often used is to alter a procedure and put a temporary select during a short period of time in the middle of a flow to be able to track down some logical problem, for example
select * from #t_transactions
and if unlucky and that same procedure is used in our Java-layer and hence mybatis we have a problem when using MSSQL JDBC.Today with JDTS that call crashes with the error above but with MSSQL nothing fails and mybatis happily makes use of the result set coming which can be disastrous depending on where this is.
So the problem here is not try to “fix” the underlaying issue with an extra result set but rather make mybatis crash when this happens. I know that this would break backwards compatibility and some strict-flag would be needed etc. to trigger this behavior.
Also from what I can see there is no way for me to build this myself with interceptors either right ?
Please look at https://github.com/kuseman/mybatis-issues/tree/master/issue-2496 now, it clearly shows the problem.