1 //----------------------------------------------------------------------
2 //
3 // PerfectJPattern: "Design patterns are good but components are better!"
4 // JpaBaseDao.java Copyright (c) 2009 Giovanni Azua Garcia
5 // bravegag@hotmail.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 3
10 // of the License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, see <http://www.gnu.org/licenses/>.
19 //
20 //----------------------------------------------------------------------
21 package org.perfectjpattern.jee.integration.dao;
22
23 import java.io.*;
24 import java.util.*;
25
26 import javax.persistence.*;
27
28 import org.apache.commons.lang.*;
29 import org.perfectjpattern.jee.api.integration.dao.*;
30
31 /**
32 * Abstract reusable JPA partial implementation of {@link IGenericReadOnlyDao}
33 * that provides automatic handling of {@link EntityManager} within a
34 * EJB container
35 *
36 * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a>
37 * @version $Revision: 1.0 $Date: Feb 11, 2009 10:17:46 AM $
38 */
39 @SuppressWarnings("hiding")
40 public
41 class JpaBaseDao<Id extends Serializable, Element>
42 implements IBaseDao<Id, Element>
43 {
44 //------------------------------------------------------------------------
45 // public
46 //------------------------------------------------------------------------
47 /**
48 * {@inheritDoc}
49 */
50 public boolean
51 contains(Element anElement)
52 throws DaoException, IllegalArgumentException
53 {
54 Validate.notNull(anElement, "'anElement' must not be null");
55
56 boolean myExists = false;
57 try
58 {
59 ISession mySession = getSession();
60
61 myExists = mySession.contains(anElement);
62
63 return myExists;
64 }
65 // CHECKSTYLE:OFF
66 catch (RuntimeException anException)
67 // CHECKSTYLE:ON
68 {
69 throw new DaoException(anException);
70 }
71 }
72
73 //------------------------------------------------------------------------
74 /**
75 * {@inheritDoc}
76 */
77 @SuppressWarnings("unchecked")
78 public int
79 count()
80 throws DaoException
81 {
82 int myCount = 0;
83
84 try
85 {
86 ISession mySession = getSession();
87
88 IQuery myQuery = mySession.createQuery("select count(e) " +
89 "from " + thePersistentClass.getSimpleName() + " e");
90
91 myCount = ((Long) myQuery.getSingleResult()).intValue();
92
93 return myCount;
94 }
95 // CHECKSTYLE:OFF
96 catch (RuntimeException anException)
97 // CHECKSTYLE:ON
98 {
99 anException.printStackTrace();
100
101 throw new DaoException(anException);
102 }
103 }
104
105 //------------------------------------------------------------------------
106 /**
107 * {@inheritDoc}
108 */
109 @SuppressWarnings("unchecked")
110 public Element
111 findById(Id anId)
112 throws DaoException, IllegalArgumentException
113 {
114 Validate.notNull(anId, "'anId' must not be null");
115
116 Element myElement = null;
117 try
118 {
119 ISession mySession = getSession();
120
121 myElement = (Element) mySession.find(getPersistentClass(), anId);
122
123 return myElement;
124 }
125 // CHECKSTYLE:OFF
126 catch (RuntimeException anException)
127 // CHECKSTYLE:ON
128 {
129 throw new DaoException(anException);
130 }
131 }
132
133 //------------------------------------------------------------------------
134 /**
135 * {@inheritDoc}
136 */
137 @SuppressWarnings("unchecked")
138 public List<Element>
139 findAll()
140 throws DaoException
141 {
142 List<Element> myElements = null;
143
144 try
145 {
146 ISession mySession = getSession();
147
148 myElements = mySession.createQuery("select e from " +
149 getPersistentClass().getSimpleName() + " e").getResultList();
150
151 return myElements;
152 }
153 // CHECKSTYLE:OFF
154 catch (RuntimeException anException)
155 // CHECKSTYLE:ON
156 {
157 throw new DaoException(anException);
158 }
159 }
160
161 //------------------------------------------------------------------------
162 /**
163 * {@inheritDoc}
164 */
165 @SuppressWarnings("unchecked")
166 public Id
167 create(Element anElement)
168 throws DaoException, IllegalArgumentException
169 {
170 Validate.notNull(anElement, "'anElement' must not be null");
171
172 Id myId = null;
173
174 try
175 {
176 ISession mySession = getSession();
177
178 myId = (Id) mySession.persist(anElement);
179
180 return myId;
181 }
182 // CHECKSTYLE:OFF
183 catch (RuntimeException anException)
184 // CHECKSTYLE:ON
185 {
186 throw new DaoException(anException);
187 }
188 }
189
190 //------------------------------------------------------------------------
191 /**
192 * {@inheritDoc}
193 */
194 public boolean
195 update(Element anElement)
196 throws DaoException
197 {
198 Validate.notNull(anElement, "'anElement' must not be null");
199
200 try
201 {
202 ISession mySession = getSession();
203
204 mySession.update(anElement);
205
206 return true;
207 }
208 // CHECKSTYLE:OFF
209 catch (RuntimeException anException)
210 // CHECKSTYLE:ON
211 {
212 throw new DaoException(anException);
213 }
214 }
215
216 //------------------------------------------------------------------------
217 /**
218 * {@inheritDoc}
219 */
220 public boolean
221 delete(Element anElement)
222 throws DaoException
223 {
224 Validate.notNull(anElement, "'anElement' must not be null");
225
226 try
227 {
228 ISession mySession = getSession();
229
230 mySession.remove(anElement);
231
232 return true;
233 }
234 // CHECKSTYLE:OFF
235 catch (RuntimeException anException)
236 // CHECKSTYLE:ON
237 {
238 throw new DaoException(anException);
239 }
240 }
241
242 //------------------------------------------------------------------------
243 /**
244 * {@inheritDoc}
245 */
246 public void
247 deleteAll()
248 throws DaoException
249 {
250 try
251 {
252 ISession mySession = getSession();
253
254 mySession.createQuery("delete from " + getPersistentClass().
255 getName()).executeUpdate();
256 }
257 // CHECKSTYLE:OFF
258 catch (RuntimeException anException)
259 // CHECKSTYLE:ON
260 {
261 throw new DaoException(anException);
262 }
263 }
264
265 //------------------------------------------------------------------------
266 /**
267 * {@inheritDoc}
268 */
269 public ITransaction
270 getTransaction()
271 {
272 return theTransactionStrategy.getTransaction();
273 }
274
275 //------------------------------------------------------------------------
276 /**
277 * {@inheritDoc}
278 */
279 public ISession
280 getSession()
281 {
282 if (!isManaged())
283 {
284 ITransaction myTransaction = getTransaction();
285 if (!myTransaction.isActive())
286 {
287 myTransaction.begin();
288 }
289 }
290
291 return theSessionStrategy.getSession();
292 }
293
294 //------------------------------------------------------------------------
295 // protected
296 //------------------------------------------------------------------------
297 /**
298 * Constructs a {@link HibernateGenericReadOnlyDao} instance from the
299 * persistent class type, the {@link ISessionStrategy} that creates
300 * {@link ISession} instances and the {@link ITransactionStrategy} that
301 * creates {@link ITransaction} instances
302 *
303 * @param aPersistentClass The persistent Java Bean class
304 * @param aSessionStrategy Factory that creates Sessions
305 * @param aTransactionStrategy Factory that creates Transaction
306 */
307 protected
308 JpaBaseDao(Class<Element> aPersistentClass,
309 ISessionStrategy aSessionStrategy,
310 ITransactionStrategy aTransactionStrategy)
311 throws IllegalArgumentException
312 {
313 assert aPersistentClass != null : "'aPersistentClass' must not be null";
314 assert !aPersistentClass.isInterface() :
315 "'aPersistentClass' must be a class type";
316 assert aSessionStrategy != null :
317 "'aDaoSessionStrategy' must not be null";
318
319 thePersistentClass = aPersistentClass;
320 theSessionStrategy = aSessionStrategy;
321 theTransactionStrategy = aTransactionStrategy;
322 }
323
324 //------------------------------------------------------------------------
325 /**
326 * Sets the {@link EntityManager}, called from a managed EJB that exposes
327 * {@link IGenericReadOnlyDao} or {@link IGenericDao} remotely.
328 *
329 * @param anEntityManager The {@link EntityManager} to set
330 * @throws IllegalArgumentException 'anEntityManager' must not be null
331 */
332 protected void
333 setEntityManager(EntityManager anEntityManager)
334 throws IllegalArgumentException
335 {
336 assert anEntityManager != null : "'anEntityManager' must not be null";
337
338 assert theSessionStrategy instanceof JpaManagedSessionStrategy :
339 "SessionStrategy must be set to JpaManagedSessionStrategy";
340
341 JpaManagedSessionStrategy mySessionStrategy =
342 (JpaManagedSessionStrategy) theSessionStrategy;
343
344 mySessionStrategy.setEntityManager(anEntityManager);
345 }
346
347 //------------------------------------------------------------------------
348 /**
349 * Returns the persistentClass
350 *
351 * @return the persistentClass
352 */
353 protected final Class<Element>
354 getPersistentClass()
355 {
356 return thePersistentClass;
357 }
358
359 //------------------------------------------------------------------------
360 /**
361 * Returns the sessionStrategy
362 *
363 * @return the sessionStrategy
364 */
365 protected final ISessionStrategy
366 getSessionStrategy()
367 {
368 return theSessionStrategy;
369 }
370
371 //------------------------------------------------------------------------
372 /**
373 * Returns the transactionStrategy
374 *
375 * @return the transactionStrategy
376 */
377 protected final ITransactionStrategy
378 getTransactionStrategy()
379 {
380 return theTransactionStrategy;
381 }
382
383 //------------------------------------------------------------------------
384 // private
385 //------------------------------------------------------------------------
386 /**
387 * Returns true if running from a Managed environment, false otherwise
388 *
389 * @return true if running from a Managed environment, false otherwise
390 */
391 private final boolean
392 isManaged()
393 {
394 boolean myManaged = theSessionStrategy instanceof
395 JpaManagedSessionStrategy;
396
397 return myManaged;
398 }
399
400 //------------------------------------------------------------------------
401 // members
402 //------------------------------------------------------------------------
403 private final Class<Element> thePersistentClass;
404 private final ISessionStrategy theSessionStrategy;
405 private final ITransactionStrategy theTransactionStrategy;
406 }