1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.submitted.cache;
17
18 import static com.googlecode.catchexception.apis.BDDCatchException.*;
19 import static org.assertj.core.api.BDDAssertions.then;
20
21 import java.io.Reader;
22 import java.lang.reflect.Field;
23
24 import org.apache.ibatis.BaseDataTest;
25 import org.apache.ibatis.annotations.CacheNamespace;
26 import org.apache.ibatis.annotations.CacheNamespaceRef;
27 import org.apache.ibatis.annotations.Property;
28 import org.apache.ibatis.builder.BuilderException;
29 import org.apache.ibatis.cache.Cache;
30 import org.apache.ibatis.cache.CacheException;
31 import org.apache.ibatis.io.Resources;
32 import org.apache.ibatis.session.SqlSession;
33 import org.apache.ibatis.session.SqlSessionFactory;
34 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
35 import org.junit.jupiter.api.Assertions;
36 import org.junit.jupiter.api.BeforeEach;
37 import org.junit.jupiter.api.Test;
38
39
40 class CacheTest {
41
42 private static SqlSessionFactory sqlSessionFactory;
43
44 @BeforeEach
45 void setUp() throws Exception {
46
47 try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/cache/mybatis-config.xml")) {
48 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
49 }
50
51
52 BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
53 "org/apache/ibatis/submitted/cache/CreateDB.sql");
54 }
55
56
57
58
59
60
61
62
63
64
65
66 @Test
67 void testplan1() {
68 try (SqlSession sqlSession1 = sqlSessionFactory.openSession(false)) {
69 PersonMapper pm = sqlSession1.getMapper(PersonMapper.class);
70 Assertions.assertEquals(2, pm.findAll().size());
71 }
72
73 try (SqlSession sqlSession2 = sqlSessionFactory.openSession(false)) {
74 try {
75 PersonMapper pm = sqlSession2.getMapper(PersonMapper.class);
76 pm.delete(1);
77 Assertions.assertEquals(1, pm.findAll().size());
78 } finally {
79 sqlSession2.commit();
80 }
81 }
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95
96 @Test
97 void testplan2() {
98 try (SqlSession sqlSession1 = sqlSessionFactory.openSession(false)) {
99 PersonMapper pm = sqlSession1.getMapper(PersonMapper.class);
100 Assertions.assertEquals(2, pm.findAll().size());
101 }
102
103 try (SqlSession sqlSession2 = sqlSessionFactory.openSession(false)) {
104 try {
105 PersonMapper pm = sqlSession2.getMapper(PersonMapper.class);
106 pm.delete(1);
107 } finally {
108 sqlSession2.rollback();
109 }
110 }
111
112 try (SqlSession sqlSession3 = sqlSessionFactory.openSession(false)) {
113 PersonMapper pm = sqlSession3.getMapper(PersonMapper.class);
114 Assertions.assertEquals(2, pm.findAll().size());
115 }
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129
130 @Test
131 void testplan3() {
132 try (SqlSession sqlSession1 = sqlSessionFactory.openSession(true)) {
133 PersonMapper pm = sqlSession1.getMapper(PersonMapper.class);
134 Assertions.assertEquals(2, pm.findAll().size());
135 }
136
137
138 try (SqlSession sqlSession2 = sqlSessionFactory.openSession(true)) {
139 PersonMapper pm = sqlSession2.getMapper(PersonMapper.class);
140 pm.delete(1);
141 }
142
143 try (SqlSession sqlSession3 = sqlSessionFactory.openSession(true)) {
144 PersonMapper pm = sqlSession3.getMapper(PersonMapper.class);
145 Assertions.assertEquals(1, pm.findAll().size());
146 }
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 @Test
164 void shouldInsertWithOptionsFlushesCache() {
165 try (SqlSession sqlSession1 = sqlSessionFactory.openSession(true)) {
166 PersonMapper pm = sqlSession1.getMapper(PersonMapper.class);
167 Assertions.assertEquals(2, pm.findAll().size());
168 }
169
170 try (SqlSession sqlSession2 = sqlSessionFactory.openSession(true)) {
171 PersonMapper pm = sqlSession2.getMapper(PersonMapper.class);
172 Person p = new Person(3, "hello", "world");
173 pm.createWithOptions(p);
174 }
175
176 try (SqlSession sqlSession3 = sqlSessionFactory.openSession(true)) {
177 PersonMapper pm = sqlSession3.getMapper(PersonMapper.class);
178 Assertions.assertEquals(3, pm.findAll().size());
179 }
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 @Test
198 void shouldApplyFlushCacheOptions() {
199 try (SqlSession sqlSession1 = sqlSessionFactory.openSession(true)) {
200 PersonMapper pm = sqlSession1.getMapper(PersonMapper.class);
201 Assertions.assertEquals(2, pm.findAll().size());
202 }
203
204 try (SqlSession sqlSession2 = sqlSessionFactory.openSession(true)) {
205 PersonMapper pm = sqlSession2.getMapper(PersonMapper.class);
206 Person p = new Person(3, "hello", "world");
207 pm.createWithoutFlushCache(p);
208 }
209
210 try (SqlSession sqlSession3 = sqlSessionFactory.openSession(true)) {
211 PersonMapper pm = sqlSession3.getMapper(PersonMapper.class);
212 Assertions.assertEquals(2, pm.findAll().size());
213 }
214
215 try (SqlSession sqlSession4 = sqlSessionFactory.openSession(true)) {
216 PersonMapper pm = sqlSession4.getMapper(PersonMapper.class);
217 Assertions.assertEquals(3, pm.findWithFlushCache().size());
218 }
219 }
220
221 @Test
222 void shouldApplyCacheNamespaceRef() {
223 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
224 PersonMapper pm = sqlSession.getMapper(PersonMapper.class);
225 Assertions.assertEquals(2, pm.findAll().size());
226 Person p = new Person(3, "hello", "world");
227 pm.createWithoutFlushCache(p);
228 }
229 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
230 PersonMapper pm = sqlSession.getMapper(PersonMapper.class);
231 Assertions.assertEquals(2, pm.findAll().size());
232 }
233 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
234 ImportantPersonMapper pm = sqlSession.getMapper(ImportantPersonMapper.class);
235 Assertions.assertEquals(3, pm.findWithFlushCache().size());
236 }
237 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
238 PersonMapper pm = sqlSession.getMapper(PersonMapper.class);
239 Assertions.assertEquals(3, pm.findAll().size());
240 Person p = new Person(4, "foo", "bar");
241 pm.createWithoutFlushCache(p);
242 }
243 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
244 SpecialPersonMapper pm = sqlSession.getMapper(SpecialPersonMapper.class);
245 Assertions.assertEquals(4, pm.findWithFlushCache().size());
246 }
247 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
248 PersonMapper pm = sqlSession.getMapper(PersonMapper.class);
249 Assertions.assertEquals(4, pm.findAll().size());
250 }
251 }
252
253 @Test
254 void shouldResultBeCachedAfterInsert() {
255 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
256 PersonMapper pm = sqlSession.getMapper(PersonMapper.class);
257
258 Person p = new Person(3, "hello", "world");
259 pm.create(p);
260
261 Assertions.assertEquals(3, pm.findAll().size());
262
263 Person p2 = new Person(4, "bonjour", "world");
264 pm.createWithoutFlushCache(p2);
265 }
266 try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
267 PersonMapper pm = sqlSession.getMapper(PersonMapper.class);
268 Assertions.assertEquals(3, pm.findAll().size());
269 }
270 }
271
272 @Test
273 void shouldApplyCustomCacheProperties() {
274 CustomCache customCache = unwrap(sqlSessionFactory.getConfiguration().getCache(CustomCacheMapper.class.getName()));
275 Assertions.assertEquals("bar", customCache.getStringValue());
276 Assertions.assertEquals(1, customCache.getIntegerValue().intValue());
277 Assertions.assertEquals(2, customCache.getIntValue());
278 Assertions.assertEquals(3, customCache.getLongWrapperValue().longValue());
279 Assertions.assertEquals(4, customCache.getLongValue());
280 Assertions.assertEquals(5, customCache.getShortWrapperValue().shortValue());
281 Assertions.assertEquals(6, customCache.getShortValue());
282 Assertions.assertEquals((float) 7.1, customCache.getFloatWrapperValue(), 1);
283 Assertions.assertEquals((float) 8.1, customCache.getFloatValue(), 1);
284 Assertions.assertEquals(9.01, customCache.getDoubleWrapperValue(), 1);
285 Assertions.assertEquals(10.01, customCache.getDoubleValue(), 1);
286 Assertions.assertEquals((byte) 11, customCache.getByteWrapperValue().byteValue());
287 Assertions.assertEquals((byte) 12, customCache.getByteValue());
288 Assertions.assertTrue(customCache.getBooleanWrapperValue());
289 Assertions.assertTrue(customCache.isBooleanValue());
290 }
291
292 @Test
293 void shouldErrorUnsupportedProperties() {
294 when(() -> sqlSessionFactory.getConfiguration().addMapper(CustomCacheUnsupportedPropertyMapper.class));
295 then(caughtException()).isInstanceOf(CacheException.class)
296 .hasMessage("Unsupported property type for cache: 'date' of type class java.util.Date");
297 }
298
299 @Test
300 void shouldErrorInvalidCacheNamespaceRefAttributesSpecifyBoth() {
301 when(() -> sqlSessionFactory.getConfiguration().getMapperRegistry()
302 .addMapper(InvalidCacheNamespaceRefBothMapper.class));
303 then(caughtException()).isInstanceOf(BuilderException.class)
304 .hasMessage("Cannot use both value() and name() attribute in the @CacheNamespaceRef");
305 }
306
307 @Test
308 void shouldErrorInvalidCacheNamespaceRefAttributesIsEmpty() {
309 when(() -> sqlSessionFactory.getConfiguration().getMapperRegistry()
310 .addMapper(InvalidCacheNamespaceRefEmptyMapper.class));
311 then(caughtException()).isInstanceOf(BuilderException.class)
312 .hasMessage("Should be specified either value() or name() attribute in the @CacheNamespaceRef");
313 }
314
315 private CustomCache unwrap(Cache cache){
316 Field field;
317 try {
318 field = cache.getClass().getDeclaredField("delegate");
319 } catch (NoSuchFieldException e) {
320 throw new IllegalStateException(e);
321 }
322 try {
323 field.setAccessible(true);
324 return (CustomCache)field.get(cache);
325 } catch (IllegalAccessException e) {
326 throw new IllegalStateException(e);
327 } finally {
328 field.setAccessible(false);
329 }
330 }
331
332 @CacheNamespace(implementation = CustomCache.class, properties = {
333 @Property(name = "date", value = "2016/11/21")
334 })
335 private interface CustomCacheUnsupportedPropertyMapper {
336 }
337
338 @CacheNamespaceRef(value = PersonMapper.class, name = "org.apache.ibatis.submitted.cache.PersonMapper")
339 private interface InvalidCacheNamespaceRefBothMapper {
340 }
341
342 @CacheNamespaceRef
343 private interface InvalidCacheNamespaceRefEmptyMapper {
344 }
345
346 }