Skip to content

Commit 0172c5b

Browse files
committed
Avoid corner case NPE when setting a parameter
1 parent cce4726 commit 0172c5b

File tree

5 files changed

+72
-0
lines changed

5 files changed

+72
-0
lines changed

src/main/java/org/apache/ibatis/scripting/defaults/DefaultParameterHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ public void setParameters(PreparedStatement ps) {
166166
if (typeHandler == null) {
167167
typeHandler = typeHandlerRegistry.getTypeHandler(actualJdbcType);
168168
}
169+
if (typeHandler == null) {
170+
throw new TypeException("Could not find type handler for Java type '" + propertyGenericType.getTypeName()
171+
+ "' nor JDBC type '" + actualJdbcType + "'");
172+
}
169173
try {
170174
typeHandler.setParameter(ps, i + 1, value, jdbcType);
171175
} catch (TypeException | SQLException e) {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.ibatis.annotations.ConstructorArgs;
2222
import org.apache.ibatis.annotations.Insert;
2323
import org.apache.ibatis.annotations.Options;
24+
import org.apache.ibatis.annotations.Param;
2425
import org.apache.ibatis.annotations.Result;
2526
import org.apache.ibatis.annotations.Results;
2627
import org.apache.ibatis.annotations.Select;
@@ -66,4 +67,7 @@ public interface Mapper {
6667

6768
@Select("select id, name, released_on from product where id = #{id}")
6869
Map<String, Object> getProductAsMap(Integer id);
70+
71+
@Insert({ "insert into vague (vague) values (#{bean})" })
72+
int insertVague(@Param("bean") VagueBean bean);
6973
}

src/test/java/org/apache/ibatis/submitted/typehandler/TypeHandlerTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
*/
1616
package org.apache.ibatis.submitted.typehandler;
1717

18+
import static org.assertj.core.api.Assertions.assertThat;
1819
import static org.junit.jupiter.api.Assertions.assertEquals;
1920
import static org.junit.jupiter.api.Assertions.assertNotNull;
21+
import static org.junit.jupiter.api.Assertions.fail;
2022

2123
import java.io.Reader;
2224
import java.sql.Time;
@@ -36,6 +38,7 @@
3638
import org.apache.ibatis.submitted.typehandler.Product.ProductIdTypeHandler;
3739
import org.apache.ibatis.type.JdbcType;
3840
import org.apache.ibatis.type.LocalDateTypeHandler;
41+
import org.apache.ibatis.type.TypeException;
3942
import org.junit.jupiter.api.BeforeEach;
4043
import org.junit.jupiter.api.Test;
4144

@@ -202,4 +205,17 @@ void shouldHandlerBePickedBasedOnRuntimeJdbcType_Map() {
202205
}
203206
}
204207

208+
@Test
209+
void shouldThrowProperExceptionWhenNoHandlerFoundForParam() {
210+
addMapper();
211+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
212+
Mapper mapper = sqlSession.getMapper(Mapper.class);
213+
mapper.insertVague(new VagueBean());
214+
fail("Should throw exception");
215+
} catch (Exception e) {
216+
assertThat(e).cause().isExactlyInstanceOf(TypeException.class).hasMessage(
217+
"Could not find type handler for Java type '" + VagueBean.class.getName() + "' nor JDBC type 'OTHER'");
218+
}
219+
}
220+
205221
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2009-2025 the original author or authors.
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+
* https://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+
package org.apache.ibatis.submitted.typehandler;
18+
19+
import java.util.Set;
20+
21+
public class VagueBean {
22+
private Integer id;
23+
private Set<?> vague;
24+
25+
public Integer getId() {
26+
return id;
27+
}
28+
29+
public void setId(Integer id) {
30+
this.id = id;
31+
}
32+
33+
public Set<?> getVague() {
34+
return vague;
35+
}
36+
37+
public void setVague(Set<?> vague) {
38+
this.vague = vague;
39+
}
40+
}

src/test/resources/org/apache/ibatis/submitted/typehandler/CreateDB.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
drop table users if exists;
1818
drop table product if exists;
19+
drop table vague if exists;
1920

2021
create table users (
2122
id int,
@@ -30,8 +31,15 @@ create table product (
3031
released_on date
3132
);
3233

34+
create table vague (
35+
id int identity,
36+
vague other
37+
);
38+
3339
insert into users (id, name, city, state) values(1, ' User1', ' Carmel ', ' IN ');
3440

3541
insert into product (id, name, released_on) values
3642
(1, 'iPod', '2001-11-10'),
3743
(2, 'iPad', '2010-04-03');
44+
45+
insert into vague (id, vague) values (1, null);

0 commit comments

Comments
 (0)