|
22 | 22 | import org.hibernate.Session; |
23 | 23 | import org.hibernate.annotations.CacheConcurrencyStrategy; |
24 | 24 | import org.hibernate.annotations.NaturalId; |
| 25 | +import org.hibernate.annotations.NaturalIdCache; |
25 | 26 | import org.hibernate.cfg.AvailableSettings; |
| 27 | +import org.hibernate.internal.SessionFactoryImpl; |
26 | 28 | import org.hibernate.jpa.QueryHints; |
27 | 29 | import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; |
28 | 30 | import org.hibernate.stat.CacheRegionStatistics; |
29 | 31 | import org.hibernate.stat.Statistics; |
30 | 32 |
|
| 33 | +import org.hibernate.testing.TestForIssue; |
31 | 34 | import org.junit.Ignore; |
32 | 35 | import org.junit.Test; |
33 | 36 |
|
34 | 37 | import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; |
| 38 | +import static org.junit.Assert.assertEquals; |
35 | 39 | import static org.junit.Assert.assertNotNull; |
36 | 40 |
|
37 | 41 |
|
38 | 42 | /** |
39 | 43 | * @author Vlad Mihalcea |
40 | 44 | */ |
41 | | -@Ignore |
| 45 | + |
42 | 46 | //@FailureExpected( jiraKey = "HHH-12146", message = "No idea why those changes cause this to fail, especially in the way it does" ) |
43 | 47 | public class SecondLevelCacheTest extends BaseEntityManagerFunctionalTestCase { |
44 | 48 |
|
@@ -251,10 +255,89 @@ public void testCache() { |
251 | 255 | }); |
252 | 256 | } |
253 | 257 |
|
| 258 | + @Test |
| 259 | + @TestForIssue( jiraKey = "HHH-14944") // issue is also reproduceable in Hibernate 5.4 |
| 260 | + public void testCacheVerifyHits() { |
| 261 | + doInJPA( this::entityManagerFactory, entityManager -> { |
| 262 | + entityManager.persist( new Person() ); |
| 263 | + Person aPerson= new Person(); |
| 264 | + aPerson.setName( "John Doe" ); |
| 265 | + aPerson.setCode( "unique-code" ); |
| 266 | + entityManager.persist( aPerson ); |
| 267 | + Session session = entityManager.unwrap(Session.class); |
| 268 | + SessionFactoryImpl sfi = (SessionFactoryImpl) session.getSessionFactory(); |
| 269 | + sfi.getStatistics().clear(); |
| 270 | + return aPerson; |
| 271 | + }); |
| 272 | + |
| 273 | + doInJPA(this::entityManagerFactory, entityManager -> { |
| 274 | + log.info("Native load by natural-id, generate first hit"); |
| 275 | + |
| 276 | + Session session = entityManager.unwrap(Session.class); |
| 277 | + SessionFactoryImpl sfi = (SessionFactoryImpl) session.getSessionFactory(); |
| 278 | + //tag::caching-entity-natural-id-example[] |
| 279 | + Person person = session |
| 280 | + .byNaturalId(Person.class) |
| 281 | + .using("code", "unique-code") |
| 282 | + .load(); |
| 283 | + |
| 284 | + assertNotNull(person); |
| 285 | + log.info("NaturalIdCacheHitCount: " + sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 286 | + log.info("SecondLevelCacheHitCount: " + sfi.getStatistics().getSecondLevelCacheHitCount()); |
| 287 | + assertEquals(1, sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 288 | + assertEquals(1, sfi.getStatistics().getSecondLevelCacheHitCount()); |
| 289 | + //end::caching-entity-natural-id-example[] |
| 290 | + }); |
| 291 | + |
| 292 | + doInJPA(this::entityManagerFactory, entityManager -> { |
| 293 | + log.info("Native load by natural-id, generate second hit"); |
| 294 | + |
| 295 | + Session session = entityManager.unwrap(Session.class); |
| 296 | + SessionFactoryImpl sfi = (SessionFactoryImpl) session.getSessionFactory(); |
| 297 | + //tag::caching-entity-natural-id-example[] |
| 298 | + Person person = session.bySimpleNaturalId(Person.class).load("unique-code"); |
| 299 | + assertNotNull(person); |
| 300 | + |
| 301 | + // resolve in persistence context (first level cache) |
| 302 | + session.bySimpleNaturalId(Person.class).load("unique-code"); |
| 303 | + log.info("NaturalIdCacheHitCount: " + sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 304 | + log.info("SecondLevelCacheHitCount: " + sfi.getStatistics().getSecondLevelCacheHitCount()); |
| 305 | + assertEquals(2, sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 306 | + assertEquals(2, sfi.getStatistics().getSecondLevelCacheHitCount()); |
| 307 | + |
| 308 | + session.clear(); |
| 309 | + // persistence context (first level cache) empty, should resolve from second level cache |
| 310 | + log.info("Native load by natural-id, generate third hit"); |
| 311 | + person = session.bySimpleNaturalId(Person.class).load("unique-code"); |
| 312 | + log.info("NaturalIdCacheHitCount: " + sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 313 | + log.info("SecondLevelCacheHitCount: " + sfi.getStatistics().getSecondLevelCacheHitCount()); |
| 314 | + assertNotNull(person); |
| 315 | + assertEquals(3, sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 316 | + assertEquals(3, sfi.getStatistics().getSecondLevelCacheHitCount()); |
| 317 | + |
| 318 | + //Remove the entity from the persistence context |
| 319 | + Long id = person.getId(); |
| 320 | + |
| 321 | + entityManager.detach(person); // still it should resolve from second level cache after this |
| 322 | + |
| 323 | + log.info("Native load by natural-id, generate 4. hit"); |
| 324 | + person = session.bySimpleNaturalId(Person.class).load("unique-code"); |
| 325 | + log.info("NaturalIdCacheHitCount: " + sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 326 | + assertEquals("we expected now 4 hits" , 4, sfi.getStatistics().getNaturalIdCacheHitCount()); |
| 327 | + assertNotNull(person); |
| 328 | + session.delete(person); // evicts natural-id from first & second level cache |
| 329 | + person = session.bySimpleNaturalId(Person.class).load("unique-code"); |
| 330 | + assertEquals(4, sfi.getStatistics().getNaturalIdCacheHitCount()); // thus hits should not increment |
| 331 | + |
| 332 | + //end::caching-entity-natural-id-example[] |
| 333 | + }); |
| 334 | + } |
| 335 | + |
254 | 336 | //tag::caching-entity-natural-id-mapping-example[] |
255 | 337 | @Entity(name = "Person") |
256 | 338 | @Cacheable |
257 | 339 | @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) |
| 340 | + @NaturalIdCache |
258 | 341 | public static class Person { |
259 | 342 |
|
260 | 343 | @Id |
|
0 commit comments