Skip to content

Commit c45029f

Browse files
committed
Fix single named argument at a sql provider method (related with #639)
1 parent 0c5f566 commit c45029f

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ private SqlSource createSqlSource(Object parameterObject) {
8080
String sql;
8181
if (parameterTypes.length == 0) {
8282
sql = (String) providerMethod.invoke(providerType.newInstance());
83-
} else if (parameterTypes.length == 1) {
83+
} else if (parameterTypes.length == 1 &&
84+
(parameterObject == null || parameterTypes[0].isAssignableFrom(parameterObject.getClass()))) {
8485
sql = (String) providerMethod.invoke(providerType.newInstance(), parameterObject);
8586
} else if (parameterObject instanceof Map) {
8687
@SuppressWarnings("unchecked")
@@ -89,7 +90,9 @@ private SqlSource createSqlSource(Object parameterObject) {
8990
} else {
9091
throw new BuilderException("Error invoking SqlProvider method ("
9192
+ providerType.getName() + "." + providerMethod.getName()
92-
+ "). Cannot invoke a method that holds multiple arguments using a specifying parameterObject. In this case, please specify a 'java.util.Map' object.");
93+
+ "). Cannot invoke a method that holds "
94+
+ (parameterTypes.length == 1 ? "named argument(@Param)": "multiple arguments")
95+
+ " using a specifying parameterObject. In this case, please specify a 'java.util.Map' object.");
9396
}
9497
Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
9598
return sqlSourceParser.parse(sql, parameterType, new HashMap<String, Object>());

src/test/java/org/apache/ibatis/submitted/sqlprovider/OurSqlBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public String buildGetUsersQuery(Map<String, Object> parameter) {
4242
return sb.toString();
4343
}
4444

45-
public String buildGetUserQuery(Integer parameter) {
45+
public String buildGetUserQuery(Number parameter) {
4646
// parameter is not a single List or Array,
4747
// so it is passed as is from the mapper
4848
return "select * from users where id = #{value}";

src/test/java/org/apache/ibatis/submitted/sqlprovider/SqlProviderTest.java

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.hamcrest.core.Is.is;
1919
import static org.junit.Assert.assertEquals;
2020
import static org.junit.Assert.assertNotNull;
21+
import static org.junit.Assert.assertNull;
2122

2223
import java.io.Reader;
2324
import java.sql.Connection;
@@ -36,7 +37,6 @@
3637
import org.apache.ibatis.session.SqlSessionFactory;
3738
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
3839
import org.junit.BeforeClass;
39-
import org.junit.Ignore;
4040
import org.junit.Rule;
4141
import org.junit.Test;
4242
import org.junit.rules.ExpectedException;
@@ -86,15 +86,21 @@ public void shouldGetTwoUsers() {
8686
}
8787
}
8888

89-
// Test for simple value
89+
// Test for simple value without @Param
9090
@Test
9191
public void shouldGetOneUser() {
9292
SqlSession sqlSession = sqlSessionFactory.openSession();
9393
try {
9494
Mapper mapper = sqlSession.getMapper(Mapper.class);
95-
User user = mapper.getUser(4);
96-
assertNotNull(user);
97-
assertEquals("User4", user.getName());
95+
{
96+
User user = mapper.getUser(4);
97+
assertNotNull(user);
98+
assertEquals("User4", user.getName());
99+
}
100+
{
101+
User user = mapper.getUser(null);
102+
assertNull(user);
103+
}
98104
} finally {
99105
sqlSession.close();
100106
}
@@ -241,18 +247,28 @@ public void shouldGetUsersByNameWithParamNameUsingMap() {
241247
}
242248
}
243249

244-
// Test for map with @Param
245-
@Ignore("TODO failing case")
250+
// Test for simple value with @Param
251+
@Test
246252
public void shouldGetUsersByNameWithParamName() {
247253
SqlSession sqlSession = sqlSessionFactory.openSession();
248254
try {
249255
Mapper mapper = sqlSession.getMapper(Mapper.class);
250-
List<User> users = mapper.getUsersByNameWithParamName("User");
251-
assertEquals(4, users.size());
252-
assertEquals("User4", users.get(0).getName());
253-
assertEquals("User3", users.get(1).getName());
254-
assertEquals("User2", users.get(2).getName());
255-
assertEquals("User1", users.get(3).getName());
256+
{
257+
List<User> users = mapper.getUsersByNameWithParamName("User");
258+
assertEquals(4, users.size());
259+
assertEquals("User4", users.get(0).getName());
260+
assertEquals("User3", users.get(1).getName());
261+
assertEquals("User2", users.get(2).getName());
262+
assertEquals("User1", users.get(3).getName());
263+
}
264+
{
265+
List<User> users = mapper.getUsersByNameWithParamName(null);
266+
assertEquals(4, users.size());
267+
assertEquals("User4", users.get(0).getName());
268+
assertEquals("User3", users.get(1).getName());
269+
assertEquals("User2", users.get(2).getName());
270+
assertEquals("User1", users.get(3).getName());
271+
}
256272
} finally {
257273
sqlSession.close();
258274
}
@@ -282,14 +298,23 @@ public void notSqlProvider() throws NoSuchMethodException {
282298
}
283299

284300
@Test
285-
public void notSupportParameterObject() throws NoSuchMethodException {
301+
public void notSupportParameterObjectOnMultipleArguments() throws NoSuchMethodException {
286302
expectedException.expect(BuilderException.class);
287303
expectedException.expectMessage(is("Error invoking SqlProvider method (org.apache.ibatis.submitted.sqlprovider.OurSqlBuilder.buildGetUsersByNameQuery). Cannot invoke a method that holds multiple arguments using a specifying parameterObject. In this case, please specify a 'java.util.Map' object."));
288304
new ProviderSqlSource(new Configuration(),
289305
Mapper.class.getMethod("getUsersByName", String.class, String.class).getAnnotation(SelectProvider.class))
290306
.getBoundSql(new Object());
291307
}
292308

309+
@Test
310+
public void notSupportParameterObjectOnNamedArgument() throws NoSuchMethodException {
311+
expectedException.expect(BuilderException.class);
312+
expectedException.expectMessage(is("Error invoking SqlProvider method (org.apache.ibatis.submitted.sqlprovider.OurSqlBuilder.buildGetUsersByNameWithParamNameQuery). Cannot invoke a method that holds named argument(@Param) using a specifying parameterObject. In this case, please specify a 'java.util.Map' object."));
313+
new ProviderSqlSource(new Configuration(),
314+
Mapper.class.getMethod("getUsersByNameWithParamName", String.class).getAnnotation(SelectProvider.class))
315+
.getBoundSql(new Object());
316+
}
317+
293318
@Test
294319
public void invokeError() throws NoSuchMethodException {
295320
expectedException.expect(BuilderException.class);

0 commit comments

Comments
 (0)