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