View Javadoc

1   /*
2    * To change this template, choose Tools | Templates
3    * and open the template in the editor.
4    */
5   package net.sf.ehcache.hibernate;
6   
7   import java.lang.reflect.Method;
8   import java.util.Date;
9   import java.util.List;
10  import java.util.Map;
11  
12  import net.sf.ehcache.hibernate.domain.Event;
13  import net.sf.ehcache.hibernate.domain.EventManager;
14  
15  import net.sf.ehcache.hibernate.domain.Item;
16  import net.sf.ehcache.hibernate.domain.Person;
17  import net.sf.ehcache.hibernate.domain.PhoneNumber;
18  import net.sf.ehcache.hibernate.domain.VersionedItem;
19  import org.hibernate.HibernateException;
20  import org.hibernate.Session;
21  import org.hibernate.SessionFactory;
22  import org.hibernate.Transaction;
23  import org.hibernate.cache.access.SoftLock;
24  import org.hibernate.cfg.Configuration;
25  import org.hibernate.stat.QueryStatistics;
26  
27  import org.hibernate.stat.SecondLevelCacheStatistics;
28  import org.hibernate.stat.Statistics;
29  
30  import org.junit.AfterClass;
31  import org.junit.BeforeClass;
32  import org.junit.Test;
33  
34  import static org.junit.Assert.assertEquals;
35  import static org.junit.Assert.assertTrue;
36  import static org.junit.Assert.fail;
37  
38  /***
39   * @author Chris Dennis
40   */
41  public class HibernateCacheTest {
42  
43      private static SessionFactory sessionFactory;
44      private static Configuration config;
45  
46      public synchronized static SessionFactory getSessionFactory() {
47          if (sessionFactory == null) {
48              try {
49                  sessionFactory = config.buildSessionFactory();
50              } catch (HibernateException ex) {
51                  System.err.println("Initial SessionFactory creation failed." + ex);
52                  throw new ExceptionInInitializerError(ex);
53              }
54          }
55          return sessionFactory;
56      }
57  
58      @BeforeClass
59      public static void setUp() {
60          System.setProperty("derby.system.home", "target/derby");
61          config = new Configuration().configure("/hibernate-config/hibernate.cfg.xml");
62          config.setProperty("hibernate.hbm2ddl.auto", "create");
63          getSessionFactory().getStatistics().setStatisticsEnabled(true);
64      }
65  
66      @AfterClass
67      public static void tearDown() {
68          getSessionFactory().close();
69      }
70  
71      @Test
72      public void testQueryCacheInvalidation() throws Exception {
73          Session s = getSessionFactory().openSession();
74          Transaction t = s.beginTransaction();
75          Item i = new Item();
76          i.setName("widget");
77          i.setDescription("A really top-quality, full-featured widget.");
78          s.persist(i);
79          t.commit();
80          s.close();
81  
82          SecondLevelCacheStatistics slcs = s.getSessionFactory().getStatistics().getSecondLevelCacheStatistics(Item.class.getName());
83  
84          assertEquals(slcs.getPutCount(), 1);
85          assertEquals(slcs.getElementCountInMemory(), 1);
86          assertEquals(slcs.getEntries().size(), 1);
87  
88          s = getSessionFactory().openSession();
89          t = s.beginTransaction();
90          i = (Item) s.get(Item.class, i.getId());
91  
92          assertEquals(slcs.getHitCount(), 1);
93          assertEquals(slcs.getMissCount(), 0);
94  
95          i.setDescription("A bog standard item");
96  
97          t.commit();
98          s.close();
99  
100         assertEquals(slcs.getPutCount(), 2);
101 
102         Object entry = slcs.getEntries().get(i.getId());
103         Map map;
104         if (entry instanceof Map) {
105             map = (Map) entry;
106         } else {
107             Method valueMethod = entry.getClass().getDeclaredMethod("getValue", (Class[]) null);
108             valueMethod.setAccessible(true);
109             map = (Map) valueMethod.invoke(entry, (Object[]) null);
110         }
111         assertTrue(map.get("description").equals("A bog standard item"));
112         assertTrue(map.get("name").equals("widget"));
113 
114         // cleanup
115         s = getSessionFactory().openSession();
116         t = s.beginTransaction();
117         s.delete(i);
118         t.commit();
119         s.close();
120     }
121 
122     @Test
123     public void testEmptySecondLevelCacheEntry() throws Exception {
124         getSessionFactory().evictEntity(Item.class.getName());
125         Statistics stats = getSessionFactory().getStatistics();
126         stats.clear();
127         SecondLevelCacheStatistics statistics = stats.getSecondLevelCacheStatistics(Item.class.getName());
128         Map cacheEntries = statistics.getEntries();
129         assertEquals(0, cacheEntries.size());
130     }
131 
132     @Test
133     public void testStaleWritesLeaveCacheConsistent() {
134         Session s = getSessionFactory().openSession();
135         Transaction txn = s.beginTransaction();
136         VersionedItem item = new VersionedItem();
137         item.setName("steve");
138         item.setDescription("steve's item");
139         s.save(item);
140         txn.commit();
141         s.close();
142 
143         Long initialVersion = item.getVersion();
144 
145         // manually revert the version property
146         item.setVersion(new Long(item.getVersion().longValue() - 1));
147 
148         try {
149             s = getSessionFactory().openSession();
150             txn = s.beginTransaction();
151             s.update(item);
152             txn.commit();
153             s.close();
154             fail("expected stale write to fail");
155         } catch (Throwable expected) {
156             // expected behavior here
157             if (txn != null) {
158                 try {
159                     txn.rollback();
160                 } catch (Throwable ignore) {
161                 }
162             }
163         } finally {
164             if (s != null && s.isOpen()) {
165                 try {
166                     s.close();
167                 } catch (Throwable ignore) {
168                 }
169             }
170         }
171 
172         // check the version value in the cache...
173         SecondLevelCacheStatistics slcs = getSessionFactory().getStatistics().getSecondLevelCacheStatistics(VersionedItem.class.getName());
174 
175         Object entry = slcs.getEntries().get(item.getId());
176         Long cachedVersionValue;
177         if (entry instanceof SoftLock) {
178             //FIXME don't know what to test here
179             //cachedVersionValue = new Long( ( (ReadWriteCache.Lock) entry).getUnlockTimestamp() );
180         } else {
181             cachedVersionValue = (Long) ((Map) entry).get("_version");
182             assertEquals(initialVersion.longValue(), cachedVersionValue.longValue());
183         }
184 
185 
186         // cleanup
187         s = getSessionFactory().openSession();
188         txn = s.beginTransaction();
189         item = (VersionedItem) s.load(VersionedItem.class, item.getId());
190         s.delete(item);
191         txn.commit();
192         s.close();
193 
194     }
195 
196     @Test
197     public void testGeneralUsage() {
198         EventManager mgr = new EventManager(getSessionFactory());
199         Statistics stats = getSessionFactory().getStatistics();
200 
201         // create 3 persons Steve, Orion, Tim
202         Person stevePerson = new Person();
203         stevePerson.setFirstname("Steve");
204         stevePerson.setLastname("Harris");
205         Long steveId = mgr.createAndStorePerson(stevePerson);
206         mgr.addEmailToPerson(steveId, "steve@tc.com");
207         mgr.addEmailToPerson(steveId, "sharrif@tc.com");
208         mgr.addTalismanToPerson(steveId, "rabbit foot");
209         mgr.addTalismanToPerson(steveId, "john de conqueroo");
210 
211         PhoneNumber p1 = new PhoneNumber();
212         p1.setNumberType("Office");
213         p1.setPhone(111111);
214         mgr.addPhoneNumberToPerson(steveId, p1);
215 
216         PhoneNumber p2 = new PhoneNumber();
217         p2.setNumberType("Home");
218         p2.setPhone(222222);
219         mgr.addPhoneNumberToPerson(steveId, p2);
220 
221         Person orionPerson = new Person();
222         orionPerson.setFirstname("Orion");
223         orionPerson.setLastname("Letizi");
224         Long orionId = mgr.createAndStorePerson(orionPerson);
225         mgr.addEmailToPerson(orionId, "orion@tc.com");
226         mgr.addTalismanToPerson(orionId, "voodoo doll");
227 
228         Long timId = mgr.createAndStorePerson("Tim", "Teck");
229         mgr.addEmailToPerson(timId, "teck@tc.com");
230         mgr.addTalismanToPerson(timId, "magic decoder ring");
231 
232         Long engMeetingId = mgr.createAndStoreEvent("Eng Meeting", stevePerson, new Date());
233         mgr.addPersonToEvent(steveId, engMeetingId);
234         mgr.addPersonToEvent(orionId, engMeetingId);
235         mgr.addPersonToEvent(timId, engMeetingId);
236 
237         Long docMeetingId = mgr.createAndStoreEvent("Doc Meeting", orionPerson, new Date());
238         mgr.addPersonToEvent(steveId, docMeetingId);
239         mgr.addPersonToEvent(orionId, docMeetingId);
240 
241         for (Event event : (List<Event>) mgr.listEvents()) {
242             mgr.listEmailsOfEvent(event.getId());
243         }
244 
245         getSessionFactory().close();
246 
247         QueryStatistics queryStats = stats.getQueryStatistics("from Event");
248         assertEquals("Cache Miss Count", 1L, queryStats.getCacheMissCount());
249         assertEquals("Cache Hit Count", 0L, queryStats.getCacheHitCount());
250         assertEquals("Cache Put Count", 1L, queryStats.getCachePutCount());
251     }
252 }