KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > roller > business > hibernate > HibernateStrategy


1 /*
2  * Created on Mar 7, 2003
3  */

4 package org.roller.business.hibernate;
5
6 import java.util.List JavaDoc;
7
8 import net.sf.hibernate.HibernateException;
9 import net.sf.hibernate.ObjectNotFoundException;
10 import net.sf.hibernate.Session;
11 import net.sf.hibernate.SessionFactory;
12 import net.sf.hibernate.type.Type;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.roller.RollerException;
17 import org.roller.RollerPermissionsException;
18 import org.roller.business.PersistenceStrategy;
19 import org.roller.model.PersistenceSession;
20 import org.roller.pojos.PersistentObject;
21 import org.roller.pojos.UserData;
22
23
24 ///////////////////////////////////////////////////////////////////////////////
25
/**
26  * Reusable Hibernate implementations of CRUD operations.
27  * @author David M Johnson
28  */

29 public class HibernateStrategy implements PersistenceStrategy
30 {
31     static final long serialVersionUID = 2561090040518169098L;
32     private static SessionFactory mSessionFactory = null;
33     private static final ThreadLocal JavaDoc mSessionTLS = new ThreadLocal JavaDoc();
34     //private static final ThreadLocal mTransactionTLS = new ThreadLocal();
35

36     private static Log mLogger =
37         LogFactory.getFactory().getInstance(HibernateStrategy.class);
38
39     //-------------------------------------------------------------------------
40
/**
41      * Construct using Hibernate Session Factory.
42      */

43     public HibernateStrategy(SessionFactory factory) throws RollerException
44     {
45         mSessionFactory = factory;
46     }
47
48     //-------------------------------------------------------------------------
49
/**
50      * Start new Roller persistence session on current thread.
51      */

52     public void begin(UserData user) throws RollerException
53     {
54         getPersistenceSession(user, true); // force create of new session
55
}
56
57     //-------------------------------------------------------------------------
58
/**
59      * Start new Roller persistence session on current thread.
60      */

61     public void setUser(UserData user) throws RollerException
62     {
63         PersistenceSession pses = getPersistenceSession(user, false);
64         pses.setUser(user);
65     }
66
67     //-------------------------------------------------------------------------
68
/**
69      * Start new Roller persistence session on current thread.
70      */

71     public UserData getUser() throws RollerException
72     {
73         PersistenceSession pses = getPersistenceSession(null, false);
74         return pses.getUser();
75     }
76
77     //-------------------------------------------------------------------------
78
/**
79      * Get existing persistence session on current thread.
80      */

81     public Session getSession() throws RollerException
82     {
83         return (Session)(getPersistenceSession(
84            UserData.ANONYMOUS_USER, false).getSessionObject());
85     }
86     
87     //-------------------------------------------------------------------------
88
/**
89      * Get existing or open new persistence session for current thread
90      * @param createNew True if existing session on thread is an warn condition.
91      */

92     public PersistenceSession getPersistenceSession(UserData user, boolean createNew)
93         throws RollerException
94     {
95         PersistenceSession ses = (PersistenceSession)mSessionTLS.get();
96         if (createNew && ses != null)
97         {
98             mLogger.warn("TLS not empty at beginnng of request");
99             release();
100             ses = null;
101         }
102         if (ses == null && user != null)
103         {
104             try
105             {
106                 Session hses = mSessionFactory.openSession();
107                 ses = new HibernatePersistenceSession(user, hses);
108             }
109             catch (Exception JavaDoc e)
110             {
111                 mLogger.error(Messages.getString(
112                     "HibernateStrategy.exceptionOpeningSession"));
113                 throw new RuntimeException JavaDoc();
114             }
115             mSessionTLS.set(ses);
116         }
117         else if (ses == null)
118         {
119             throw new RollerException(
120                 "MUST specify user for new persistence session");
121         }
122         return ses;
123     }
124
125     //-------------------------------------------------------------------------
126
/**
127      * This is called on error to start a new Hibernate session.
128      * Gavin: "make sure you never catch + handle an exception and
129      * then keep using the session (ObjectNotFoundException included!)
130      */

131     private void newSession() throws RollerException
132     {
133         PersistenceSession pses = getPersistenceSession(null, false);
134         UserData user = pses.getUser();
135         release();
136         getPersistenceSession(user, true);
137     }
138     
139     //-------------------------------------------------------------------------
140
/**
141      * Release database session, rolls back any uncommitted changes.
142      */

143     public void release() throws RollerException
144     {
145         PersistenceSession pses = (PersistenceSession)mSessionTLS.get();
146         if ( null == pses ) return; // there is no session to release
147
mSessionTLS.set(null); // sets thread's session to null
148
Session ses = (Session)pses.getSessionObject();
149         if (ses != null)
150         {
151             try
152             {
153                 if (ses.isOpen())
154                 {
155                     ses.close();
156                 }
157             }
158             catch (Throwable JavaDoc he)
159             {
160                     mLogger.error("ERROR cleaning up Hibernate session", he);
161             }
162         }
163         ses = null;
164     }
165
166     //-------------------------------------------------------------------------
167
/**
168      * Remove object from persistence storage.
169      * @param clazz Class of object to remove.
170      * @param id Id of object to remove.
171      * @throws RollerException Error deleting object.
172      */

173     public void remove( String JavaDoc id, Class JavaDoc clazz ) throws RollerException
174     {
175         if ( id == null )
176         {
177             throw new RollerException(Messages.getString(
178                 "HibernateStrategy.nullNotValidId"));
179         }
180         if ( clazz == null )
181         {
182             throw new RollerException(Messages.getString(
183                 "HibernateStrategy.nullNotValidClass"));
184         }
185
186         // Create persistent instance and delete it
187
PersistentObject obj;
188         try
189         {
190             obj = (PersistentObject)getSession().load(clazz,id);
191             if (obj.canSave())
192             {
193                 getSession().delete(obj);
194             }
195             else
196             {
197                 throw new RollerPermissionsException("DENIED: cannot remove");
198             }
199         }
200         catch (HibernateException e)
201         {
202             String JavaDoc msg = Messages.formatString(
203                 "HibernateStrategy.exceptionRemoving",id,clazz.getName());
204             mLogger.error(msg, e);
205
206             newSession();
207             throw new RollerException(e);
208         }
209     }
210
211     //-------------------------------------------------------------------------
212
/**
213      * Remove object from persistence storage.
214      */

215     public void remove(PersistentObject po) throws RollerException
216     {
217         if (!po.canSave())
218         {
219             throw new RollerPermissionsException(
220                 "DENIED: cannot remove: "+po.toString());
221         }
222         try
223         {
224             if (po.getId() != null) // no need to delete transient object
225
{
226                 getSession().delete(po);
227             }
228         }
229         catch (HibernateException e)
230         {
231             String JavaDoc msg = Messages.formatString(
232                 "HibernateStrategy.exceptionRemoving",po.getId());
233             mLogger.error(msg, e);
234             newSession();
235             throw new RollerException(e);
236         }
237     }
238
239     //-------------------------------------------------------------------------
240
/**
241      * Retrieve object, begins and ends its own transaction.
242      * @param clazz Class of object to retrieve.
243      * @param id Id of object to retrieve.
244      * @return Object Object retrieved.
245      * @throws RollerException Error retrieving object.
246      */

247     public PersistentObject load(String JavaDoc id, Class JavaDoc clazz)
248         throws RollerException
249     {
250         if ( id == null )
251         {
252             throw new RollerException(Messages.getString(
253                 "HibernateStrategy.nullNotValidId"));
254         }
255
256         if ( clazz == null )
257         {
258             throw new RollerException(Messages.getString(
259                 "HibernateStrategy.nullNotValidClass"));
260         }
261
262         Object JavaDoc obj = null;
263         Session ses = getSession();
264         try
265         {
266             obj = (PersistentObject)ses.load( clazz, id );
267         }
268         catch (Exception JavaDoc e)
269         {
270             if (mLogger.isDebugEnabled())
271             {
272                 if (e instanceof ObjectNotFoundException)
273                 {
274                     mLogger.debug("No " + clazz.getName() + " found for ID:" + id);
275                 }
276                 else
277                 {
278                     String JavaDoc msg = Messages.formatString(
279                      "HibernateStrategy.exceptionRetrieving", id, clazz.getName());
280                     mLogger.debug(msg, e);
281                 }
282             }
283             newSession();
284         }
285         return (PersistentObject)obj;
286     }
287
288     //-------------------------------------------------------------------------
289
/**
290      * Store object using an existing transaction.
291      */

292     public PersistentObject store(PersistentObject obj)
293         throws RollerException
294     {
295         if ( obj == null )
296         {
297             throw new RollerException(Messages.getString(
298                 "HibernateStrategy.nullPassedIn"));
299         }
300         if (!obj.canSave())
301         {
302             throw new RollerPermissionsException(
303                 "DENIED: cannot save: "+obj.toString());
304         }
305         Session ses = getSession();
306         try
307         {
308             // TODO: better to use ses.saveOrUpdate() here, if possible
309
if ( obj.getId() == null || obj.getId().trim().equals("") )
310             {
311                 // Object has never been written to database, so save it.
312
// This makes obj into a persistent instance.
313
ses.save(obj);
314             }
315
316             if ( !ses.contains(obj) )
317             {
318                 // Object has been written to database, but instance passed in
319
// is not a persistent instance, so must be loaded into session.
320
PersistentObject vo =
321                     (PersistentObject)ses.load(obj.getClass(),obj.getId());
322                 vo.setData(obj);
323                 obj = vo;
324             }
325         }
326         catch (HibernateException e)
327         {
328             String JavaDoc msg = Messages.formatString(
329                 "HibernateStrategy.exceptionStoring",obj.getId());
330             mLogger.error(msg, e);
331             newSession();
332             throw new RollerException(msg,e);
333         }
334         return obj;
335     }
336
337     //-------------------------------------------------------------------------
338
/**
339      * Execute Hibernate HSQL query
340      */

341     public List JavaDoc query( String JavaDoc query, Object JavaDoc[] args, Object JavaDoc[] types)
342         throws RollerException
343     {
344         return query(query, args, (Type[])types);
345     }
346
347     //-------------------------------------------------------------------------
348
/**
349      * Execute Hibernate HSQL query
350      */

351     public List JavaDoc query( String JavaDoc query, Object JavaDoc[] args, Type[] types )
352         throws RollerException
353     {
354         if ( query == null )
355           {
356               throw new RollerException(Messages.getString(
357                 "HibernateStrategy.nullNotValidQuery"));
358           }
359
360           if ( args == null )
361           {
362               throw new RollerException(Messages.getString(
363                 "HibernateStrategy.nullNotValidArgArray"));
364           }
365
366           if ( types == null )
367           {
368               throw new RollerException(Messages.getString(
369                 "HibernateStrategy.nullNotValidArrayType"));
370           }
371
372           try
373           {
374               if (query.indexOf("$") > -1)
375               {
376                   query = query.replaceAll("\\$\\d+", "\\?");
377               }
378               return getSession().find(query,args,types);
379           }
380           catch (Exception JavaDoc e)
381           {
382               String JavaDoc msg = Messages.getString("HibernateStrategy.duringQuery");
383               mLogger.error(msg, e);
384               newSession();
385               throw new RollerException(msg,e);
386           }
387     }
388
389     //-------------------------------------------------------------------------
390
/**
391      * Execute Hibernate HSQL query
392      */

393     public List JavaDoc query( String JavaDoc query )
394         throws RollerException
395     {
396         try
397         {
398             if (query.indexOf("$") > -1)
399             {
400                 query = query.replaceAll("\\$\\d+", "\\?");
401             }
402             return getSession().find(query);
403         }
404         catch (Exception JavaDoc e)
405         {
406             String JavaDoc msg = Messages.getString("HibernateStrategy.duringQuery");
407             mLogger.error(msg, e);
408             newSession();
409             throw new RollerException(msg,e);
410         }
411     }
412
413     //-------------------------------------------------------------------------
414
/**
415      * Commits current transaction, if there is one, does not release session.
416      */

417     public void commit() throws RollerException
418     {
419         try
420         {
421             if (mSessionTLS.get()!=null)
422             {
423                 getSession().flush();
424
425                 // can't call commit when autocommit is true
426
if (!getSession().connection().getAutoCommit())
427                 {
428                     getSession().connection().commit();
429                 }
430             }
431         }
432         catch (Exception JavaDoc he) // HibernateExeption or SQLException
433
{
434             newSession();
435             throw new RollerException(he);
436         }
437     }
438
439     //-------------------------------------------------------------------------
440
/**
441      * Rollback uncommitted changes, does not release session.
442      */

443     public void rollback() throws RollerException
444     {
445         // Can't call rollback when autoCommit=true
446
try
447         {
448             if (!getSession().connection().getAutoCommit())
449             {
450                 getSession().connection().rollback();
451             }
452         }
453         catch (Exception JavaDoc he)
454         {
455             newSession();
456             if (mLogger.isDebugEnabled())
457             {
458                 mLogger.debug("ERROR during rollback",he);
459             }
460         }
461     }
462 }
463
464
Popular Tags