17
17
18
18
import java .sql .ResultSet ;
19
19
import java .sql .SQLException ;
20
- import java .util .ArrayList ;
21
20
import java .util .HashMap ;
22
21
import java .util .List ;
23
22
import java .util .Locale ;
@@ -45,7 +44,6 @@ public class NestedResultSetHandler extends FastResultSetHandler {
45
44
46
45
private final Map <CacheKey , Object > objectCache = new HashMap <CacheKey , Object >();
47
46
private final Map <CacheKey , Object > ancestorCache = new HashMap <CacheKey , Object >();
48
- private final List <Object > unsortedRowHandlerElements = new ArrayList <Object >();
49
47
50
48
public NestedResultSetHandler (Executor executor , MappedStatement mappedStatement , ParameterHandler parameterHandler , ResultHandler resultHandler , BoundSql boundSql , RowBounds rowBounds ) {
51
49
super (executor , mappedStatement , parameterHandler , resultHandler , boundSql , rowBounds );
@@ -65,11 +63,20 @@ private void ensureNoRowBounds(RowBounds rowBounds) {
65
63
// HANDLE RESULT SETS
66
64
//
67
65
66
+ @ Override
67
+ protected void handleResultSet (ResultSet rs , ResultMap resultMap , List <Object > multipleResults , ResultColumnCache resultColumnCache ) throws SQLException {
68
+ if (resultHandler != null && configuration .isSafeResultHandlerEnabled () && !mappedStatement .isResultOrdered ()) {
69
+ throw new ExecutorException ("Mapped Statements with nested result mappings cannot be safely used with a custom ResultHandler. "
70
+ + "Use safeResultHandlerEnabled=false setting to bypass this check "
71
+ + "or ensure your statement returns ordered data and set resultOrdered=true on it." );
72
+ }
73
+ super .handleResultSet (rs , resultMap , multipleResults , resultColumnCache );
74
+ }
75
+
68
76
@ Override
69
77
protected void cleanUpAfterHandlingResultSet () {
70
78
super .cleanUpAfterHandlingResultSet ();
71
79
objectCache .clear ();
72
- unsortedRowHandlerElements .clear ();
73
80
}
74
81
75
82
//
@@ -85,25 +92,21 @@ protected void handleRowValues(ResultSet rs, ResultMap resultMap, ResultHandler
85
92
final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap (rs , resultMap , null );
86
93
final CacheKey rowKey = createRowKey (discriminatedResultMap , rs , null , resultColumnCache );
87
94
Object partialObject = objectCache .get (rowKey );
88
- if (mappedStatement .isResultOrdered ()) { // issue #577
95
+ if (mappedStatement .isResultOrdered ()) { // issue #577 && #542
89
96
if (partialObject == null && rowValue != null ) {
90
- objectCache .clear ();
97
+ objectCache .clear ();
91
98
callResultHandler (resultHandler , resultContext , rowValue );
92
- }
99
+ }
93
100
rowValue = getRowValue (rs , discriminatedResultMap , rowKey , rowKey , null , resultColumnCache , partialObject );
94
101
} else {
95
102
rowValue = getRowValue (rs , discriminatedResultMap , rowKey , rowKey , null , resultColumnCache , partialObject );
96
103
if (partialObject == null ) {
97
- unsortedRowHandlerElements . add ( rowValue ); // issue #542
104
+ callResultHandler ( resultHandler , resultContext , rowValue );
98
105
}
99
106
}
100
107
}
101
- if (mappedStatement .isResultOrdered ()) {
102
- if (rowValue != null ) callResultHandler (resultHandler , resultContext , rowValue );
103
- } else {
104
- for (Object o : unsortedRowHandlerElements ) {
105
- callResultHandler (resultHandler , resultContext , o );
106
- }
108
+ if (rowValue != null && mappedStatement .isResultOrdered ()) {
109
+ callResultHandler (resultHandler , resultContext , rowValue );
107
110
}
108
111
}
109
112
0 commit comments