Skip to content

Commit 8f210c9

Browse files
committed
http://code.google.com/p/mybatis/issues/detail?id=769 : Order Matters for ResultMap Extension
1 parent 7a58062 commit 8f210c9

File tree

11 files changed

+382
-4
lines changed

11 files changed

+382
-4
lines changed

src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Collection;
2828
import java.util.HashMap;
2929
import java.util.HashSet;
30+
import java.util.Iterator;
3031
import java.util.List;
3132
import java.util.Locale;
3233
import java.util.Map;
@@ -56,6 +57,7 @@
5657
import org.apache.ibatis.annotations.UpdateProvider;
5758
import org.apache.ibatis.binding.BindingException;
5859
import org.apache.ibatis.builder.BuilderException;
60+
import org.apache.ibatis.builder.IncompleteElementException;
5961
import org.apache.ibatis.builder.MapperBuilderAssistant;
6062
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
6163
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
@@ -114,7 +116,27 @@ public void parse() {
114116
parseCacheRef();
115117
Method[] methods = type.getMethods();
116118
for (Method method : methods) {
117-
parseStatement(method);
119+
try {
120+
parseStatement(method);
121+
} catch (IncompleteElementException e) {
122+
configuration.addIncompleteMethod(new MethodResolver(this, method));
123+
}
124+
}
125+
}
126+
parsePendingMethods();
127+
}
128+
129+
private void parsePendingMethods() {
130+
Collection<MethodResolver> incompleteMethods = configuration.getIncompleteMethods();
131+
synchronized (incompleteMethods) {
132+
Iterator<MethodResolver> iter = incompleteMethods.iterator();
133+
while (iter.hasNext()) {
134+
try {
135+
iter.next().resolve();
136+
iter.remove();
137+
} catch (IncompleteElementException e) {
138+
// This method is still missing a resource
139+
}
118140
}
119141
}
120142
}
@@ -213,7 +235,7 @@ private Discriminator applyDiscriminator(String resultMapId, Class<?> resultType
213235
return null;
214236
}
215237

216-
private void parseStatement(Method method) {
238+
void parseStatement(Method method) {
217239
Class<?> parameterTypeClass = getParameterType(method);
218240
LanguageDriver languageDriver = getLanguageDriver(method);
219241
SqlSource sqlSource = getSqlSourceFromAnnotations(method, parameterTypeClass, languageDriver);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2009-2013 The MyBatis Team
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.builder.annotation;
17+
18+
import java.lang.reflect.Method;
19+
20+
public class MethodResolver {
21+
private final MapperAnnotationBuilder annotationBuilder;
22+
private Method method;
23+
24+
public MethodResolver(MapperAnnotationBuilder annotationBuilder, Method method) {
25+
this.annotationBuilder = annotationBuilder;
26+
this.method = method;
27+
}
28+
29+
public void resolve() {
30+
annotationBuilder.parseStatement(method);
31+
}
32+
33+
}

src/main/java/org/apache/ibatis/session/Configuration.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2012 The MyBatis Team
2+
* Copyright 2009-2013 The MyBatis Team
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
2727
import org.apache.ibatis.binding.MapperRegistry;
2828
import org.apache.ibatis.builder.CacheRefResolver;
2929
import org.apache.ibatis.builder.ResultMapResolver;
30+
import org.apache.ibatis.builder.annotation.MethodResolver;
3031
import org.apache.ibatis.builder.xml.XMLStatementBuilder;
3132
import org.apache.ibatis.cache.Cache;
3233
import org.apache.ibatis.cache.decorators.FifoCache;
@@ -125,6 +126,8 @@ public class Configuration {
125126
protected final Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<XMLStatementBuilder>();
126127
protected final Collection<CacheRefResolver> incompleteCacheRefs = new LinkedList<CacheRefResolver>();
127128
protected final Collection<ResultMapResolver> incompleteResultMaps = new LinkedList<ResultMapResolver>();
129+
protected final Collection<MethodResolver> incompleteMethods = new LinkedList<MethodResolver>();
130+
128131
/*
129132
* A map holds cache-ref relationship. The key is the namespace that
130133
* references a cache bound to another namespace and the value is the
@@ -188,7 +191,7 @@ public boolean isSafeResultHandlerEnabled() {
188191
return safeResultHandlerEnabled;
189192
}
190193

191-
@Deprecated // "Not needed as of the fix for issue #542")
194+
@Deprecated // "Not needed as of the fix for issue #542"
192195
public void setSafeResultHandlerEnabled(boolean safeResultHandlerEnabled) {
193196
this.safeResultHandlerEnabled = safeResultHandlerEnabled;
194197
}
@@ -549,6 +552,14 @@ public void addIncompleteResultMap(ResultMapResolver resultMapResolver) {
549552
incompleteResultMaps.add(resultMapResolver);
550553
}
551554

555+
public void addIncompleteMethod(MethodResolver builder) {
556+
incompleteMethods.add(builder);
557+
}
558+
559+
public Collection<MethodResolver> getIncompleteMethods() {
560+
return incompleteMethods;
561+
}
562+
552563
public MappedStatement getMappedStatement(String id) {
553564
return this.getMappedStatement(id, true);
554565
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2009-2013 The MyBatis Team
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.extendresultmap;
17+
18+
import java.io.Reader;
19+
import java.sql.Connection;
20+
21+
import org.apache.ibatis.io.Resources;
22+
import org.apache.ibatis.jdbc.ScriptRunner;
23+
import org.apache.ibatis.session.SqlSession;
24+
import org.apache.ibatis.session.SqlSessionFactory;
25+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
26+
import org.junit.BeforeClass;
27+
import org.junit.Test;
28+
29+
public class BaseTest {
30+
31+
private static SqlSessionFactory sqlSessionFactory;
32+
33+
@BeforeClass
34+
public static void setUp() throws Exception {
35+
// create a SqlSessionFactory
36+
Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/extendresultmap/mybatis-config.xml");
37+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
38+
reader.close();
39+
40+
// populate in-memory database
41+
SqlSession session = sqlSessionFactory.openSession();
42+
Connection conn = session.getConnection();
43+
reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/extendresultmap/CreateDB.sql");
44+
ScriptRunner runner = new ScriptRunner(conn);
45+
runner.setLogWriter(null);
46+
runner.runScript(reader);
47+
reader.close();
48+
session.close();
49+
}
50+
51+
@Test
52+
public void shouldGetAUser() {
53+
SqlSession sqlSession = sqlSessionFactory.openSession();
54+
try {
55+
TestMapperY mapper = sqlSession.getMapper(TestMapperY.class);
56+
mapper.retrieveTestString();
57+
} finally {
58+
sqlSession.close();
59+
}
60+
}
61+
62+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--
2+
-- Copyright 2009-2013 The MyBatis Team
3+
--
4+
-- Licensed under the Apache License, Version 2.0 (the "License");
5+
-- you may not use this file except in compliance with the License.
6+
-- You may obtain a copy of the License at
7+
--
8+
-- http://www.apache.org/licenses/LICENSE-2.0
9+
--
10+
-- Unless required by applicable law or agreed to in writing, software
11+
-- distributed under the License is distributed on an "AS IS" BASIS,
12+
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
-- See the License for the specific language governing permissions and
14+
-- limitations under the License.
15+
--
16+
17+
drop table test if exists;
18+
19+
create table test (
20+
A VARCHAR(32) not null,
21+
B VARCHAR(32) not null
22+
);
23+
24+
INSERT INTO test VALUES('A1', 'B1');
25+
INSERT INTO test VALUES('A2', 'B2');
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2009-2013 The MyBatis Team
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.extendresultmap;
17+
18+
import org.apache.ibatis.annotations.ResultMap;
19+
import org.apache.ibatis.annotations.Select;
20+
21+
public interface TestMapperX {
22+
@Select("SELECT * FROM test AS t LIMIT 1")
23+
@ResultMap("map")
24+
TestModel retrieveTestString();
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!--
3+
Copyright 2009-2013 The MyBatis Team
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
18+
<mapper namespace="org.apache.ibatis.submitted.extendresultmap.TestMapperX">
19+
20+
<resultMap type="org.apache.ibatis.submitted.extendresultmap.TestModel"
21+
id="map">
22+
<result property="b" column="A" />
23+
</resultMap>
24+
25+
</mapper>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2009-2013 The MyBatis Team
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.extendresultmap;
17+
18+
import org.apache.ibatis.annotations.ResultMap;
19+
import org.apache.ibatis.annotations.Select;
20+
21+
public interface TestMapperY {
22+
@Select("SELECT * FROM test AS t LIMIT 1")
23+
@ResultMap("map")
24+
TestModel retrieveTestString();
25+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!--
3+
Copyright 2009-2013 The MyBatis Team
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
18+
<mapper namespace="org.apache.ibatis.submitted.extendresultmap.TestMapperY">
19+
20+
<resultMap type="org.apache.ibatis.submitted.extendresultmap.TestModel"
21+
id="map" extends="org.apache.ibatis.submitted.extendresultmap.TestMapperX.map">
22+
23+
<result property="a" column="B" />
24+
</resultMap>
25+
26+
</mapper>

0 commit comments

Comments
 (0)