Skip to content

Commit df5f7b7

Browse files
committed
Corrected #93 : Added autoMapping attribute to collection and association. Auto-mapping setting is not inherited to nested result maps (the same behavior as version 3.2.3). 'autoMapping' is ignored when 'select' or 'resultMap' is found in the same element. Related to the discussion in #112.
1 parent e94d49c commit df5f7b7

File tree

11 files changed

+165
-27
lines changed

11 files changed

+165
-27
lines changed

src/main/java/org/apache/ibatis/builder/xml/mybatis-3-mapper.dtd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ notNullColumn CDATA #IMPLIED
116116
columnPrefix CDATA #IMPLIED
117117
resultSet CDATA #IMPLIED
118118
foreignColumn CDATA #IMPLIED
119+
autoMapping (true|false) #IMPLIED
119120
>
120121

121122
<!ELEMENT association (constructor?,id*,result*,association*,collection*, discriminator?)>
@@ -131,6 +132,7 @@ notNullColumn CDATA #IMPLIED
131132
columnPrefix CDATA #IMPLIED
132133
resultSet CDATA #IMPLIED
133134
foreignColumn CDATA #IMPLIED
135+
autoMapping (true|false) #IMPLIED
134136
>
135137

136138
<!ELEMENT discriminator (case+)>

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

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQL
330330
if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
331331
final MetaObject metaObject = configuration.newMetaObject(resultObject);
332332
boolean foundValues = resultMap.getConstructorResultMappings().size() > 0;
333-
if (shouldApplyAutomaticMappings(resultMap, null, !AutoMappingBehavior.NONE.equals(configuration.getAutoMappingBehavior()))) {
333+
if (shouldApplyAutomaticMappings(resultMap, !AutoMappingBehavior.NONE.equals(configuration.getAutoMappingBehavior()))) {
334334
foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;
335335
}
336336
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
@@ -341,9 +341,8 @@ private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQL
341341
return resultObject;
342342
}
343343

344-
private boolean shouldApplyAutomaticMappings(ResultMap resultMap, Boolean parentAutoMapping, boolean def) {
345-
return resultMap.getAutoMapping() != null ? resultMap.getAutoMapping()
346-
: parentAutoMapping != null ? parentAutoMapping : def;
344+
private boolean shouldApplyAutomaticMappings(ResultMap resultMap, boolean def) {
345+
return resultMap.getAutoMapping() != null ? resultMap.getAutoMapping() : def;
347346
}
348347

349348
private ResultLoaderMap instantiateResultLoaderMap() {
@@ -725,9 +724,9 @@ private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap r
725724
nestedResultObjects.clear();
726725
storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
727726
}
728-
rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject, null);
727+
rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject);
729728
} else {
730-
rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject, null);
729+
rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, rowKey, null, partialObject);
731730
if (partialObject == null) {
732731
storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
733732
}
@@ -742,25 +741,25 @@ private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap r
742741
// GET VALUE FROM ROW FOR NESTED RESULT MAP
743742
//
744743

745-
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey combinedKey, CacheKey absoluteKey, String columnPrefix, Object partialObject, Boolean parentAutoMapping) throws SQLException {
744+
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey combinedKey, CacheKey absoluteKey, String columnPrefix, Object partialObject) throws SQLException {
746745
Object resultObject = partialObject;
747746
if (resultObject != null) {
748747
final MetaObject metaObject = configuration.newMetaObject(resultObject);
749748
ancestorObjects.put(absoluteKey, resultObject);
750-
applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false, parentAutoMapping);
749+
applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);
751750
ancestorObjects.remove(absoluteKey);
752751
} else {
753752
final ResultLoaderMap lazyLoader = instantiateResultLoaderMap();
754753
resultObject = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
755754
if (resultObject != null && !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
756755
final MetaObject metaObject = configuration.newMetaObject(resultObject);
757756
boolean foundValues = resultMap.getConstructorResultMappings().size() > 0;
758-
if (shouldApplyAutomaticMappings(resultMap, parentAutoMapping, AutoMappingBehavior.FULL.equals(configuration.getAutoMappingBehavior()))) {
757+
if (shouldApplyAutomaticMappings(resultMap, AutoMappingBehavior.FULL.equals(configuration.getAutoMappingBehavior()))) {
759758
foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
760759
}
761760
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
762761
ancestorObjects.put(absoluteKey, resultObject);
763-
foundValues = applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true, parentAutoMapping) || foundValues;
762+
foundValues = applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;
764763
ancestorObjects.remove(absoluteKey);
765764
foundValues = (lazyLoader != null && lazyLoader.size() > 0) || foundValues;
766765
resultObject = foundValues ? resultObject : null;
@@ -774,7 +773,7 @@ private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey c
774773
// NESTED RESULT MAP (JOIN MAPPING)
775774
//
776775

777-
private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String parentPrefix, CacheKey parentRowKey, boolean newObject, Boolean parentAutoMapping) {
776+
private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String parentPrefix, CacheKey parentRowKey, boolean newObject) {
778777
boolean foundValues = false;
779778
for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) {
780779
final String nestedResultMapId = resultMapping.getNestedResultMapId();
@@ -792,7 +791,7 @@ private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap result
792791
boolean knownValue = (rowValue != null);
793792
final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject);
794793
if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw.getResultSet())) {
795-
rowValue = getRowValue(rsw, nestedResultMap, combinedKey, rowKey, columnPrefix, rowValue, parentAutoMapping != null ? parentAutoMapping : resultMap.getAutoMapping());
794+
rowValue = getRowValue(rsw, nestedResultMap, combinedKey, rowKey, columnPrefix, rowValue);
796795
if (rowValue != null && !knownValue) {
797796
if (collectionProperty != null) {
798797
final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty);

src/site/es/xdoc/sqlmap-xml.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,13 @@ public class User {
10661066
sólo creará un objeto hijo si alguna de estas columnas no es nula. Pueden indicarse una lista de columnas usando la coma como separador.
10671067
</td>
10681068
</tr>
1069+
<tr>
1070+
<td><code>autoMapping</code></td>
1071+
<td>If present, MyBatis will enable or disable automapping when mapping the result to this property.
1072+
This attribute overrides the global autoMappingBehavior.
1073+
Note that it has no effect on an external resultMap, so it is pointless to use it with <code>select</code> or <code>resultMap</code> attribute. Default value: unset.
1074+
</td>
1075+
</tr>
10691076
</tbody>
10701077
</table>
10711078

src/site/ja/xdoc/sqlmap-xml.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,11 @@ public class User {
12561256
ネストされた結果をマッピングする際、デフォルトでは子オブジェクトのプロパティに対応する列のうち一つでも null でない値がセットされているものがあれば子オブジェクトが生成されます。notNullColumn に列名(複数可)を指定しておくと、指定された列に null 以外の値がセットされた場合にのみ子オブジェクトが生成されます。デフォルト:未指定
12571257
</td>
12581258
</tr>
1259+
<tr>
1260+
<td><code>autoMapping</code></td>
1261+
<td>このプロパティに結果をマッピングする際、自動マッピングを使用するかどうかを true / false で指定します。ここでの指定はグローバルな設定(autoMappingBehavior)より優先されます。この設定は別の場所で定義されている ResultMap には適用されませんので、<code>select</code> や <code>resultMap</code> が指定されている場合は無効となります。デフォルト:未指定
1262+
</td>
1263+
</tr>
12591264
</tbody>
12601265
</table>
12611266

src/site/ko/xdoc/sqlmap-xml.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,13 @@ prop1, prop2 형태로 셋팅하게 될 것이다.</td>
10441044
specified using a comma as a separator. Default value: unset.
10451045
</td>
10461046
</tr>
1047+
<tr>
1048+
<td><code>autoMapping</code></td>
1049+
<td>If present, MyBatis will enable or disable automapping when mapping the result to this property.
1050+
This attribute overrides the global autoMappingBehavior.
1051+
Note that it has no effect on an external resultMap, so it is pointless to use it with <code>select</code> or <code>resultMap</code> attribute. Default value: unset.
1052+
</td>
1053+
</tr>
10471054
</tbody>
10481055
</table>
10491056

src/site/xdoc/sqlmap-xml.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,13 @@ public class User {
13651365
specified using a comma as a separator. Default value: unset.
13661366
</td>
13671367
</tr>
1368+
<tr>
1369+
<td><code>autoMapping</code></td>
1370+
<td>If present, MyBatis will enable or disable automapping when mapping the result to this property.
1371+
This attribute overrides the global autoMappingBehavior.
1372+
Note that it has no effect on an external resultMap, so it is pointless to use it with <code>select</code> or <code>resultMap</code> attribute. Default value: unset.
1373+
</td>
1374+
</tr>
13681375
</tbody>
13691376
</table>
13701377

src/site/zh/xdoc/sqlmap-xml.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,13 @@ resultMap
14111411
specified using a comma as a separator. Default value: unset.
14121412
</td>
14131413
</tr>
1414+
<tr>
1415+
<td><code>autoMapping</code></td>
1416+
<td>If present, MyBatis will enable or disable auto-mapping when mapping the result to this property.
1417+
This attribute overrides the global autoMappingBehavior.
1418+
Note that it has no effect on an external resultMap, so it is pointless to use it with <code>select</code> or <code>resultMap</code> attribute. Default value: unset.
1419+
</td>
1420+
</tr>
14141421
</tbody>
14151422
</table>
14161423

src/test/java/org/apache/ibatis/submitted/automapping/AutomappingTest.java

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public static void setUp() throws Exception {
5353

5454
@Test
5555
public void shouldGetAUser() {
56+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.NONE);
5657
SqlSession sqlSession = sqlSessionFactory.openSession();
5758
try {
5859
Mapper mapper = sqlSession.getMapper(Mapper.class);
@@ -64,17 +65,98 @@ public void shouldGetAUser() {
6465
}
6566

6667
@Test
67-
public void shouldGetAUserWithPets() {
68+
public void shouldNotInheritAutoMappingInherited_InlineNestedResultMap() {
69+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.NONE);
6870
SqlSession sqlSession = sqlSessionFactory.openSession();
6971
try {
7072
Mapper mapper = sqlSession.getMapper(Mapper.class);
71-
User user = mapper.getUserWithPets(2);
73+
User user = mapper.getUserWithPets_Inline(2);
7274
Assert.assertEquals(Integer.valueOf(2), user.getId());
7375
Assert.assertEquals("User2", user.getName());
74-
Assert.assertEquals(2, user.getPets().size());
75-
Assert.assertEquals(Integer.valueOf(12), user.getPets().get(0).getPetId());
76+
Assert.assertNull("should not inherit auto-mapping", user.getPets().get(0).getPetName());
77+
Assert.assertEquals("John", user.getPets().get(0).getBreeder().getBreederName());
78+
} finally {
79+
sqlSession.close();
80+
}
81+
}
82+
83+
@Test
84+
public void shouldNotInheritAutoMappingInherited_ExternalNestedResultMap() {
85+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.NONE);
86+
SqlSession sqlSession = sqlSessionFactory.openSession();
87+
try {
88+
Mapper mapper = sqlSession.getMapper(Mapper.class);
89+
User user = mapper.getUserWithPets_External(2);
90+
Assert.assertEquals(Integer.valueOf(2), user.getId());
91+
Assert.assertEquals("User2", user.getName());
92+
Assert.assertNull("should not inherit auto-mapping", user.getPets().get(0).getPetName());
93+
Assert.assertEquals("John", user.getPets().get(0).getBreeder().getBreederName());
94+
} finally {
95+
sqlSession.close();
96+
}
97+
}
98+
99+
@Test
100+
public void shouldIgnorePartialAutoMappingBehavior_InlineNestedResultMap() {
101+
// For nested resultMaps, PARTIAL works the same as NONE
102+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
103+
SqlSession sqlSession = sqlSessionFactory.openSession();
104+
try {
105+
Mapper mapper = sqlSession.getMapper(Mapper.class);
106+
User user = mapper.getUserWithPets_Inline(2);
107+
Assert.assertEquals(Integer.valueOf(2), user.getId());
108+
Assert.assertEquals("User2", user.getName());
109+
Assert.assertNull("should not inherit auto-mapping", user.getPets().get(0).getPetName());
110+
Assert.assertEquals("John", user.getPets().get(0).getBreeder().getBreederName());
111+
} finally {
112+
sqlSession.close();
113+
}
114+
}
115+
116+
@Test
117+
public void shouldRespectFullAutoMappingBehavior_InlineNestedResultMap() {
118+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.FULL);
119+
SqlSession sqlSession = sqlSessionFactory.openSession();
120+
try {
121+
Mapper mapper = sqlSession.getMapper(Mapper.class);
122+
User user = mapper.getUserWithPets_Inline(2);
123+
Assert.assertEquals(Integer.valueOf(2), user.getId());
124+
Assert.assertEquals("User2", user.getName());
125+
Assert.assertEquals("Chien", user.getPets().get(0).getPetName());
126+
Assert.assertEquals("John", user.getPets().get(0).getBreeder().getBreederName());
127+
} finally {
128+
sqlSession.close();
129+
}
130+
}
131+
132+
@Test
133+
public void shouldIgnorePartialAutoMappingBehavior_ExternalNestedResultMap() {
134+
// For nested resultMaps, PARTIAL works the same as NONE
135+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
136+
SqlSession sqlSession = sqlSessionFactory.openSession();
137+
try {
138+
Mapper mapper = sqlSession.getMapper(Mapper.class);
139+
User user = mapper.getUserWithPets_External(2);
140+
Assert.assertEquals(Integer.valueOf(2), user.getId());
141+
Assert.assertEquals("User2", user.getName());
142+
Assert.assertNull("should not inherit auto-mapping", user.getPets().get(0).getPetName());
143+
Assert.assertEquals("John", user.getPets().get(0).getBreeder().getBreederName());
144+
} finally {
145+
sqlSession.close();
146+
}
147+
}
148+
149+
@Test
150+
public void shouldRespectFullAutoMappingBehavior_ExternalNestedResultMap() {
151+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.FULL);
152+
SqlSession sqlSession = sqlSessionFactory.openSession();
153+
try {
154+
Mapper mapper = sqlSession.getMapper(Mapper.class);
155+
User user = mapper.getUserWithPets_External(2);
156+
Assert.assertEquals(Integer.valueOf(2), user.getId());
157+
Assert.assertEquals("User2", user.getName());
158+
Assert.assertEquals("Chien", user.getPets().get(0).getPetName());
76159
Assert.assertEquals("John", user.getPets().get(0).getBreeder().getBreederName());
77-
Assert.assertEquals("Kotetsu", user.getPets().get(1).getPetName());
78160
} finally {
79161
sqlSession.close();
80162
}

src/test/java/org/apache/ibatis/submitted/automapping/Mapper.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ public interface Mapper {
2121

2222
User getUser(Integer id);
2323

24-
User getUserWithPets(Integer id);
24+
User getUserWithPets_Inline(Integer id);
25+
26+
User getUserWithPets_External(Integer id);
2527

2628
List<Book> getBooks();
27-
29+
2830
Article getArticle();
2931
}

src/test/java/org/apache/ibatis/submitted/automapping/Mapper.xml

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,48 @@
2727
<resultMap type="org.apache.ibatis.submitted.automapping.User" id="result" autoMapping="true">
2828
</resultMap>
2929

30-
<select id="getUserWithPets" resultMap="resultWithPets">
30+
<sql id="selectUserPetBreeder">
3131
select users.id, users.name,
3232
pets.id as petId, pets.name as petName,
3333
breeder.id as breederId, breeder.name as breederName
3434
from users
3535
left join pets on pets.owner = users.id
3636
left join breeder on breeder.id = pets.breeder
3737
where users.id = #{id}
38+
</sql>
39+
40+
<select id="getUserWithPets_Inline" resultMap="resultWithPets_Inline">
41+
<include refid="selectUserPetBreeder" />
3842
</select>
3943

40-
<resultMap type="org.apache.ibatis.submitted.automapping.User" id="resultWithPets" autoMapping="true">
44+
<resultMap type="org.apache.ibatis.submitted.automapping.User" id="resultWithPets_Inline" autoMapping="true">
4145
<id column="id" property="id"/>
4246
<collection property="pets" ofType="org.apache.ibatis.submitted.automapping.Pet">
4347
<id column="petId" property="petId"/>
44-
<association property="breeder" javaType="org.apache.ibatis.submitted.automapping.Breeder" />
48+
<association property="breeder" javaType="org.apache.ibatis.submitted.automapping.Breeder" autoMapping="true"/>
4549
</collection>
4650
</resultMap>
47-
51+
52+
<select id="getUserWithPets_External" resultMap="resultWithPets_External">
53+
<include refid="selectUserPetBreeder" />
54+
</select>
55+
56+
<resultMap type="org.apache.ibatis.submitted.automapping.User" id="resultWithPets_External" autoMapping="true">
57+
<id column="id" property="id"/>
58+
<collection property="pets" resultMap="petResult" />
59+
</resultMap>
60+
61+
<resultMap type="org.apache.ibatis.submitted.automapping.Pet" id="petResult">
62+
<id property="petId" column="petId" />
63+
<association property="breeder" resultMap="breederResult" />
64+
</resultMap>
65+
66+
<resultMap type="org.apache.ibatis.submitted.automapping.Breeder" id="breederResult" autoMapping="true">
67+
<id property="breederId" column="breederId" />
68+
</resultMap>
69+
4870
<resultMap type="org.apache.ibatis.submitted.automapping.Book" id="bookResult">
49-
<result property="name" column="name"/>
71+
<result property="name" column="name"/>
5072
</resultMap>
5173

5274
<select id="getBooks" resultMap="bookResult">

0 commit comments

Comments
 (0)