1 /*** $Id: DAOHibernateActionProcessorImpl.java,v 1.1.1.1 2004/05/18 10:50:12 mochoa Exp $ */
2 package org.j2ee.dao;
3
4 //java
5 import java.io.Serializable;
6 import java.util.MissingResourceException;
7
8 // SQL
9 import java.sql.Connection;
10
11 // Hibernate
12 import net.sf.hibernate.HibernateException;
13 import net.sf.hibernate.MappingException;
14 import net.sf.hibernate.Query;
15 import net.sf.hibernate.Session;
16 import net.sf.hibernate.SessionFactory;
17 import net.sf.hibernate.Transaction;
18 import net.sf.hibernate.cfg.Configuration;
19 import net.sf.hibernate.dialect.Dialect;
20
21 // log4j
22 import org.apache.log4j.Logger;
23
24 // DAO
25 import org.j2ee.dao.errors.ErrorMapper;
26 import org.j2ee.dao.errors.ErrorMapperFactory;
27
28 /***
29 * <br>
30 * Based on an example of book <i>Code Notes for J2EE, Edited by GREGORY BRILL,
31 * e-ISBN 0-679-64727-9</i>
32 * <br>
33 * Last modified $Date: 2004/05/18 10:50:12 $
34 * @version $Revision: 1.1.1.1 $
35 * @author mochoa (mochoa@users.sourceforge.net)*/
36 public class DAOHibernateActionProcessorImpl implements DAOActionProcessor {
37
38 private static Logger log = Logger.getLogger(DAOHibernateActionProcessorImpl.class);
39 private static ErrorMapper errorMapper = null;
40
41 /***
42 * connection used if you want to replace Hibernate internal connection pooling
43 * Hibernate documentation recomend do not use external connection, but this is
44 * implemented for compatiblibity with DAO JDBC
45 */
46 private Connection connection = null;
47
48 /***
49 * Private instance values for this processor.
50 * Be carefull in multi-threading enviroments, multiples thread will use the same
51 * processor intance, then they will share these instance variables.
52 * Many of them could be have several colateral effects, for example share the
53 * transaction object.
54 * If the thread A takes the processor p1 and execute the method beginTransaction()
55 * they change the values of the private attribute externalTransaction to true.
56 * If the thread B takes the same processor (p1) but it do not execute beginTransaction()
57 * the efect will be the same, because the processor already have setted the attribute to
58 * true and then it will use the the transaction openned by the thread A
59 * Also Session and Transaction Hibernate objects are NOT THREADSAFE.
60 */
61 private Session session = null;
62 private Transaction transaction = null;
63 private boolean externalSession = false;
64 private boolean externalTransaction = false;
65
66 private static Configuration cfg = null;
67 private static SessionFactory factory = null;
68
69 public static synchronized Configuration getConfiguration() throws HibernateException
70 {
71 if (cfg==null) {
72 cfg = new Configuration();
73 String xmlFile = null;
74 try {
75 xmlFile = DAOFactory.getProperties().getString("hibernate.cfg");
76 } catch (MissingResourceException e) {
77 xmlFile = "/hibernate.cfg.xml";
78 }
79 log.debug(".getConfiguration - Start reading "+xmlFile);
80 cfg.configure(xmlFile);
81 log.debug(".getSessionFactory - Building a new Session factory.");
82 factory = cfg.buildSessionFactory();
83 log.debug(".getConfiguration - Creating a new Configuration instance.");
84 }
85 return cfg;
86 }
87
88 public static synchronized SessionFactory getSessionFactory() throws HibernateException
89 {
90 if (factory==null)
91 try {
92 if (cfg==null)
93 cfg = getConfiguration();
94 } catch (HibernateException he) {
95 log.warn(".getSessionFactory - There where errors building a new Session factory.",he);
96 he.printStackTrace(System.err);
97 }
98 return factory;
99 }
100
101 /***
102 * A wrapped method for Hibernate addClass(Class persistenClass)
103 * but without throwing the MappingException.
104 * @param clazz
105 */
106 public void addClass(Class clazz) {
107 try {
108 getConfiguration().addClass(clazz);
109 }
110 catch (MappingException me) {
111 log.error(".addClass Failed to register the persistent class",me);
112 } catch (HibernateException he) {
113 log.error(".addClass Failed to get the configuration object",he);
114 }
115 }
116
117 /***
118 * Return an ErrorMapper object to translate SQLException or other kind of exception
119 * to a common error list code
120 * @return ErrorMapper
121 */
122 public ErrorMapper getErrorMapper() {
123 if (errorMapper == null) {
124 String dl = cfg.getProperties().getProperty("dialect");
125 if ("net.sf.hibernate.dialect.DB2Dialect".equals(dl))
126 errorMapper = ErrorMapperFactory.getErrorMapper(ErrorMapperFactory.DB2);
127 else if ("net.sf.hibernate.dialect.OracleDialect".equals(dl))
128 errorMapper = ErrorMapperFactory.getErrorMapper(ErrorMapperFactory.ORACLE);
129 else if ("net.sf.hibernate.dialect.HSQLDialect".equals(dl))
130 errorMapper = ErrorMapperFactory.getErrorMapper(ErrorMapperFactory.HSQL);
131 else
132 log.warn(".getErrorMapper - Can't find Error mapper for: "+dl);
133 }
134 return errorMapper;
135 }
136
137 /***
138 * Provides the JDBC connection object stored into the private instance
139 * @return a JDBC connection
140 */
141 public Connection getConnection() { return connection; }
142
143 /***
144 * Provide an external JDBC Connection to be used by Hibernate
145 * @param connection
146 */
147 public void setConnection(Connection connection) {
148 this.connection = connection;
149 }
150
151 /***
152 * get/start an Hibernate Session object to be used for external controled action.
153 * @throws HibernateException if there are errors open the session
154 */
155 public void getSession() throws DAOException {
156 if (session==null) {
157 try {
158 if (connection==null)
159 session = getSessionFactory().openSession();
160 else
161 session = getSessionFactory().openSession(this.connection);
162 } catch (HibernateException he) {
163 throw new DAOException("Error openning hibernate session",he);
164 }
165 log.debug(".getSession - Create a new session for this Processor.");
166 externalSession = true;
167 }
168 }
169
170 /***
171 * Start a new Hibernate transaction.
172 * This method is usefull when you need to manage Macro Actions.
173 * The first action takes the session and the transaction a pass it to the others.
174 * For example.
175 * @throws HibernateException
176 */
177 public void beginTransaction() throws DAOException {
178 if (transaction==null) {
179 try {
180 transaction = session.beginTransaction();
181 externalTransaction = true;
182 } catch (HibernateException he) {
183 transaction = null;
184 externalTransaction = false;
185 throw new DAOException("Error starting the transaction",he);
186 }
187 }
188 log.debug(".beginTransaction - Start a new transaction in this Processor.");
189 }
190
191 /***
192 * commit a started transaction.
193 * @throws HibernateException
194 */
195 public void commitTransaction() throws DAOException {
196 if (transaction!=null)
197 try {
198 transaction.commit();
199 } catch (HibernateException he) {
200 throw new DAOException("Error commiting the transaction",he);
201 } finally {
202 transaction = null;
203 externalTransaction = false;
204 }
205 log.debug(".commitTransaction - Commit a started transaction in this Processor.");
206 }
207
208 /***
209 * rollback a started transaction.
210 * @throws HibernateException
211 */
212 public void rollbackTransaction() throws DAOException {
213 if (transaction!=null)
214 try {
215 transaction.rollback();
216 } catch (HibernateException he) {
217 throw new DAOException("Error when rollback the transaction",he);
218 } finally {
219 transaction = null;
220 externalTransaction = false;
221 }
222 log.debug(".rollbackTransaction - Rollback a started transaction in this Processor.");
223 }
224
225 /***
226 * close a started session
227 * @throws HibernateException
228 */
229 public void closeSession() throws DAOException {
230 if (session!=null) {
231 try {
232 session.close();
233 } catch (HibernateException he) {
234 throw new DAOException("Error closing the session",he);
235 } finally {
236 // If you close the session, also close the transaction.
237 transaction = null;
238 externalTransaction = false;
239 session = null;
240 externalSession = false;
241 }
242 log.debug(".closeSession - Close an openned session in this Processor.");
243 }
244 }
245
246 /***
247 * execute a command action.
248 * If the session/transaction is already started use them.
249 * if not, open a session/transaction and close them immediatelly.
250 * @param acmd
251 * @throws DAOException
252 */
253 public void process(DAOAction acmd) throws DAOException {
254 HibernateDAOAction cmd;
255 if (acmd instanceof HibernateDAOAction)
256 cmd = (HibernateDAOAction)acmd;
257 else
258 throw new DAOException("Expected a HibernateDAOAction instance");
259 long pproc = System.currentTimeMillis();//profiling;
260 long pexec = 0;
261 Session s = null;
262 Transaction tx = null;
263 try {
264 if (!externalSession) {
265 try {
266 if (connection==null)
267 s = getSessionFactory().openSession();
268 else
269 s = getSessionFactory().openSession(this.connection);
270 } catch (HibernateException e) {
271 log.warn(".process - There where errors on getSessionFactory().openSession()",e);
272 throw new DAOException("There where error when open session.",e);
273 }
274 log.debug(".process - Start an internal session in this Processor.");
275 } else
276 s = session;
277 if (!externalTransaction) {
278 tx = s.beginTransaction();
279 externalTransaction = false;
280 log.debug(".process - Start an internal transaction in this Processor.");
281 } else
282 tx = transaction;
283 if (cmd.isSave() || cmd.isUpdate() || cmd.isDelete()) { // Handle save, update delete commands.
284 Object[] params = cmd.getParameters();
285 String[] names= cmd.getNamesForParams();
286 if (params.length!=1)
287 throw new DAOException("Save, Update or Delete requires only one param (The transfer Object).");
288 pexec = System.currentTimeMillis();//profiling
289 if (cmd.isSave())
290 s.save(params[0]);
291 else if (cmd.isUpdate())
292 s.saveOrUpdate(params[0]);
293 else
294 s.delete(params[0]);
295 cmd.handleResult();
296 pexec = System.currentTimeMillis()-pexec;//profiling
297 } else if (cmd.isLoad()) {
298 Object[] params = cmd.getParameters();
299 String[] names= cmd.getNamesForParams();
300 if (params.length!=2)
301 throw new DAOException("Load requires only two param (The transfer Object and the Key).");
302 pexec = System.currentTimeMillis();//profiling
303 Serializable key = (Serializable)params[1];
304 Object result = s.load(params[0].getClass(),key);
305 cmd.handleResult(result);
306 pexec = System.currentTimeMillis()-pexec;//profiling
307 } else if (cmd.isSqlQuery()) { // Handle Queries using SQL format
308 Query qry = s.createSQLQuery(cmd.getSQL(),
309 cmd.getReturnAliasForSqlQuery(),
310 cmd.getReturnClassForSqlQuery());
311 qry.setCacheable(cmd.isCaching());
312 Object[] params = cmd.getParameters();
313 String[] names= cmd.getNamesForParams();
314 if (params!=null)
315 for (int i=0;i<params.length;i++)
316 qry.setParameter(names[i],params[i]);
317 pexec = System.currentTimeMillis();//profiling
318 cmd.handleResults(qry.list());
319 pexec = System.currentTimeMillis()-pexec;//profiling
320 } else if (cmd.isHqlQuery()) { // Handle Queries using HQL syntax
321 Query qry = s.createQuery(cmd.getHQL());
322 qry.setCacheable(cmd.isCaching());
323 Object[] params = cmd.getParameters();
324 String[] names= cmd.getNamesForParams();
325 if (params!=null)
326 for (int i=0;i<params.length;i++)
327 qry.setParameter(names[i],params[i]);
328 pexec = System.currentTimeMillis();//profiling
329 cmd.handleResults(qry.list());
330 pexec = System.currentTimeMillis()-pexec;//profiling
331 }
332 if (log.isDebugEnabled())
333 log.debug(".process - Hibernate elapsed time = "+pexec+" ms.");
334 if (!externalTransaction) {
335 log.debug(".process - Commit an internal transaction in this Processor.");
336 tx.commit();
337 }
338 } catch (Exception e) {
339 try {
340 if (tx!=null && !externalTransaction) {
341 log.debug(".process - Rollback an internal transaction in this Processor.",e);
342 tx.rollback();
343 }
344 } catch (Exception txe) {
345 log.warn(".process - There where errors on tx.rollback()",txe);
346 throw new DAOException("There where errors on tx.rollback()",txe);
347 }
348 throw new DAOException("DAOHibernateActionProcessorImpl error on process",e);
349 } finally {
350 try {
351 if (!externalSession) {
352 log.debug(".process - Close an internal session in this Processor.");
353 if (s!=null)
354 s.close();
355 }
356 } catch (HibernateException txe) {
357 log.warn(".process - There where errors on s.close()",txe);
358 throw new DAOException("There where errors on s.close()",txe);
359 }
360 }
361 pproc = System.currentTimeMillis()-pproc;//profiling
362 if (log.isDebugEnabled())
363 log.debug(".process - Processor elapsed time = "+pproc+" ms.");
364 }
365 }
This page was automatically generated by Maven