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