Skip to content

Commit eb0edc4

Browse files
committed
fixes #215 There are two separate changes here. 1) A circulary referenced resultMap will be filled with ancestor only when the columnPrefix attribute is not specified for the nested result mapping. 2) When columnPrefix is specified for a nested result mapping and there is no column with that prefix in the result set, skip filling the nested result mapping to prevent stack overflow.
1 parent 3f19d04 commit eb0edc4

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -887,23 +887,27 @@ private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap result
887887
try {
888888
final String columnPrefix = getColumnPrefix(parentPrefix, resultMapping);
889889
final ResultMap nestedResultMap = getNestedResultMap(rsw.getResultSet(), nestedResultMapId, columnPrefix);
890-
Object ancestorObject = ancestorObjects.get(nestedResultMapId);
891-
if (ancestorObject != null) {
892-
if (newObject) {
893-
linkObjects(metaObject, resultMapping, ancestorObject); // issue #385
894-
}
895-
} else {
896-
final CacheKey rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
897-
final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
898-
Object rowValue = nestedResultObjects.get(combinedKey);
899-
boolean knownValue = (rowValue != null);
900-
instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); // mandatory
901-
if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw.getResultSet())) {
902-
rowValue = getRowValue(rsw, nestedResultMap, combinedKey, columnPrefix, rowValue);
903-
if (rowValue != null && !knownValue) {
904-
linkObjects(metaObject, resultMapping, rowValue);
905-
foundValues = true;
890+
if (resultMapping.getColumnPrefix() == null) {
891+
// try to fill circular reference only when columnPrefix
892+
// is not specified for the nested result map (issue #215)
893+
Object ancestorObject = ancestorObjects.get(nestedResultMapId);
894+
if (ancestorObject != null) {
895+
if (newObject) {
896+
linkObjects(metaObject, resultMapping, ancestorObject); // issue #385
906897
}
898+
continue;
899+
}
900+
}
901+
final CacheKey rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
902+
final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
903+
Object rowValue = nestedResultObjects.get(combinedKey);
904+
boolean knownValue = (rowValue != null);
905+
instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); // mandatory
906+
if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw)) {
907+
rowValue = getRowValue(rsw, nestedResultMap, combinedKey, columnPrefix, rowValue);
908+
if (rowValue != null && !knownValue) {
909+
linkObjects(metaObject, resultMapping, rowValue);
910+
foundValues = true;
907911
}
908912
}
909913
} catch (SQLException e) {
@@ -925,20 +929,26 @@ private String getColumnPrefix(String parentPrefix, ResultMapping resultMapping)
925929
return columnPrefixBuilder.length() == 0 ? null : columnPrefixBuilder.toString().toUpperCase(Locale.ENGLISH);
926930
}
927931

928-
private boolean anyNotNullColumnHasValue(ResultMapping resultMapping, String columnPrefix, ResultSet rs) throws SQLException {
932+
private boolean anyNotNullColumnHasValue(ResultMapping resultMapping, String columnPrefix, ResultSetWrapper rsw) throws SQLException {
929933
Set<String> notNullColumns = resultMapping.getNotNullColumns();
930-
boolean anyNotNullColumnHasValue = true;
931934
if (notNullColumns != null && !notNullColumns.isEmpty()) {
932-
anyNotNullColumnHasValue = false;
935+
ResultSet rs = rsw.getResultSet();
933936
for (String column: notNullColumns) {
934937
rs.getObject(prependPrefix(column, columnPrefix));
935938
if (!rs.wasNull()) {
936-
anyNotNullColumnHasValue = true;
937-
break;
939+
return true;
940+
}
941+
}
942+
return false;
943+
} else if (columnPrefix != null) {
944+
for (String columnName : rsw.getColumnNames()) {
945+
if (columnName.toUpperCase().startsWith(columnPrefix.toUpperCase())) {
946+
return true;
938947
}
939948
}
949+
return false;
940950
}
941-
return anyNotNullColumnHasValue;
951+
return true;
942952
}
943953

944954
private ResultMap getNestedResultMap(ResultSet rs, String nestedResultMapId, String columnPrefix) throws SQLException {

src/test/java/org/apache/ibatis/submitted/ancestor_ref/AncestorRefTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ public static void setUp() throws Exception {
5050
session.close();
5151
}
5252

53-
@Ignore("issue #215")
5453
@Test
5554
public void testCircularAssociation() {
5655
SqlSession sqlSession = sqlSessionFactory.openSession();
@@ -63,7 +62,6 @@ public void testCircularAssociation() {
6362
}
6463
}
6564

66-
@Ignore("issue #215")
6765
@Test
6866
public void testCircularCollection() {
6967
SqlSession sqlSession = sqlSessionFactory.openSession();

0 commit comments

Comments
 (0)