Skip to content

Commit a4b9394

Browse files
committed
Avoid NPE on MyBatisCursorItemReader
Fixes gh-237
1 parent 776468e commit a4b9394

File tree

2 files changed

+110
-2
lines changed

2 files changed

+110
-2
lines changed

src/main/java/org/mybatis/spring/batch/MyBatisCursorItemReader.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,12 @@ protected void doOpen() throws Exception {
7171

7272
@Override
7373
protected void doClose() throws Exception {
74-
cursor.close();
75-
sqlSession.close();
74+
if (cursor != null) {
75+
cursor.close();
76+
}
77+
if (sqlSession != null) {
78+
sqlSession.close();
79+
}
7680
cursorIterator = null;
7781
}
7882

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* Copyright 2010-2017 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+
* 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.mybatis.spring.batch;
17+
18+
import java.util.Arrays;
19+
import java.util.Collections;
20+
import java.util.List;
21+
22+
import org.apache.ibatis.cursor.Cursor;
23+
import org.apache.ibatis.session.ExecutorType;
24+
import org.apache.ibatis.session.SqlSession;
25+
import org.apache.ibatis.session.SqlSessionFactory;
26+
import org.assertj.core.api.Assertions;
27+
import org.junit.jupiter.api.BeforeEach;
28+
import org.junit.jupiter.api.Test;
29+
import org.mockito.Mock;
30+
import org.mockito.Mockito;
31+
import org.mockito.MockitoAnnotations;
32+
import org.springframework.batch.item.ExecutionContext;
33+
import org.springframework.batch.item.ItemStreamException;
34+
35+
/**
36+
* Tests for {@link MyBatisCursorItemReader}.
37+
*/
38+
class MyBatisCursorItemReaderTest {
39+
40+
@Mock
41+
private SqlSessionFactory sqlSessionFactory;
42+
43+
@Mock
44+
private SqlSession sqlSession;
45+
46+
@Mock
47+
private Cursor<Object> cursor;
48+
49+
@BeforeEach
50+
void setUp() {
51+
MockitoAnnotations.initMocks(this);
52+
}
53+
54+
@Test
55+
void testCloseOnFailing() throws Exception {
56+
57+
Mockito.when(this.sqlSessionFactory.openSession(ExecutorType.SIMPLE))
58+
.thenReturn(this.sqlSession);
59+
Mockito.when(this.cursor.iterator()).thenReturn(getFoos().iterator());
60+
Mockito.when(this.sqlSession.selectCursor("selectFoo", Collections.singletonMap("id", 1)))
61+
.thenThrow(new RuntimeException("error."));
62+
63+
MyBatisCursorItemReader<Foo> itemReader = new MyBatisCursorItemReader<>();
64+
itemReader.setSqlSessionFactory(this.sqlSessionFactory);
65+
itemReader.setQueryId("selectFoo");
66+
itemReader.setParameterValues(Collections.singletonMap("id", 1));
67+
itemReader.afterPropertiesSet();
68+
69+
ExecutionContext executionContext = new ExecutionContext();
70+
try {
71+
itemReader.open(executionContext);
72+
} catch (ItemStreamException e) {
73+
Assertions.assertThat(e).hasMessage("Failed to initialize the reader")
74+
.hasCause(new RuntimeException("error."));
75+
} finally {
76+
itemReader.close();
77+
Mockito.verify(this.sqlSession).close();
78+
}
79+
80+
}
81+
82+
@Test
83+
void testCloseBeforeOpen() {
84+
MyBatisCursorItemReader<Foo> itemReader = new MyBatisCursorItemReader<>();
85+
itemReader.close();
86+
}
87+
88+
private List<Object> getFoos() {
89+
return Arrays.asList(new Foo("foo1"), new Foo("foo2"), new Foo("foo3"));
90+
}
91+
92+
private static class Foo {
93+
private final String name;
94+
95+
public Foo(String name) {
96+
this.name = name;
97+
}
98+
99+
public String getName() {
100+
return this.name;
101+
}
102+
}
103+
104+
}

0 commit comments

Comments
 (0)