Skip to content

Commit 8e7b38a

Browse files
committed
refs #364 Throws exception when collection type is ambiguous.
1 parent 94272d7 commit 8e7b38a

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,26 @@ private String processNestedResultMappings(XNode context, List<ResultMapping> re
405405
|| "collection".equals(context.getName())
406406
|| "case".equals(context.getName())) {
407407
if (context.getStringAttribute("select") == null) {
408+
validateCollection(context, enclosingType);
408409
ResultMap resultMap = resultMapElement(context, resultMappings, enclosingType);
409410
return resultMap.getId();
410411
}
411412
}
412413
return null;
413414
}
414415

416+
protected void validateCollection(XNode context, Class<?> enclosingType) {
417+
if ("collection".equals(context.getName()) && context.getStringAttribute("resultMap") == null
418+
&& context.getStringAttribute("resultType") == null) {
419+
MetaClass metaResultType = MetaClass.forClass(enclosingType, configuration.getReflectorFactory());
420+
String property = context.getStringAttribute("property");
421+
if (!metaResultType.hasSetter(property)) {
422+
throw new BuilderException(
423+
"Ambiguous collection type for property '" + property + "'. You must specify 'resultType' or 'resultMap'.");
424+
}
425+
}
426+
}
427+
415428
private void bindMapperForNamespace() {
416429
String namespace = builderAssistant.getCurrentNamespace();
417430
if (namespace != null) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright 2009-2018 the original author or authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<!DOCTYPE mapper
20+
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
21+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
22+
23+
<mapper
24+
namespace="org.apache.ibatis.submitted.stringlist.MapperInvalid">
25+
26+
<resultMap type="map" id="invalidResultMap">
27+
<id column="id" property="id" />
28+
<!-- collection type is not resolvable -->
29+
<collection property="groups" ofType="string">
30+
<result column="group_id" />
31+
</collection>
32+
</resultMap>
33+
34+
</mapper>

src/test/java/org/apache/ibatis/submitted/stringlist/StringListTest.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
*/
1616
package org.apache.ibatis.submitted.stringlist;
1717

18+
import static org.junit.Assert.*;
19+
1820
import java.io.Reader;
1921
import java.util.List;
2022

2123
import org.apache.ibatis.BaseDataTest;
24+
import org.apache.ibatis.exceptions.PersistenceException;
2225
import org.apache.ibatis.io.Resources;
2326
import org.apache.ibatis.session.SqlSession;
2427
import org.apache.ibatis.session.SqlSessionFactory;
@@ -40,7 +43,7 @@ public static void setUp() throws Exception {
4043

4144
// populate in-memory database
4245
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
43-
"org/apache/ibatis/submitted/stringlist/CreateDB.sql");
46+
"org/apache/ibatis/submitted/stringlist/CreateDB.sql");
4447
}
4548

4649
@Test
@@ -54,4 +57,15 @@ public void shouldGetAUser() {
5457
}
5558
}
5659

60+
@Test
61+
public void shouldFailFastIfCollectionTypeIsAmbiguous() throws Exception {
62+
try (Reader reader = Resources
63+
.getResourceAsReader("org/apache/ibatis/submitted/stringlist/mybatis-config-invalid.xml")) {
64+
new SqlSessionFactoryBuilder().build(reader);
65+
fail("Should throw exception when collection type is unresolvable.");
66+
} catch (PersistenceException e) {
67+
assertTrue(e.getMessage()
68+
.contains("Ambiguous collection type for property 'groups'. You must specify 'resultType' or 'resultMap'."));
69+
}
70+
}
5771
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!--
3+
4+
Copyright 2009-2018 the original author or authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<!DOCTYPE configuration
20+
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
21+
"http://mybatis.org/dtd/mybatis-3-config.dtd">
22+
23+
<configuration>
24+
25+
<environments default="development">
26+
<environment id="development">
27+
<transactionManager type="JDBC">
28+
<property name="" value="" />
29+
</transactionManager>
30+
<dataSource type="UNPOOLED">
31+
<property name="driver" value="org.hsqldb.jdbcDriver" />
32+
<property name="url" value="jdbc:hsqldb:mem:stringlistinvalid" />
33+
<property name="username" value="sa" />
34+
</dataSource>
35+
</environment>
36+
</environments>
37+
38+
<mappers>
39+
<mapper resource="org/apache/ibatis/submitted/stringlist/MapperInvalid.xml" />
40+
</mappers>
41+
42+
</configuration>

0 commit comments

Comments
 (0)