1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package tinlizard.dao.jpa;
20
21 import tinlizard.model.CurrentUser;
22 import tinlizard.model.TinLizardConfig;
23
24 import java.util.Collection;
25 import java.util.Date;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import javax.persistence.EntityExistsException;
30 import javax.persistence.EntityManager;
31 import javax.persistence.EntityManagerFactory;
32 import javax.persistence.EntityNotFoundException;
33 import javax.persistence.EntityTransaction;
34 import javax.persistence.NoResultException;
35 import javax.persistence.NonUniqueResultException;
36 import javax.persistence.Persistence;
37 import javax.persistence.Query;
38
39 import org.apache.log4j.Logger;
40 import org.apache.lucene.analysis.standard.StandardAnalyzer;
41 import org.apache.lucene.queryParser.MultiFieldQueryParser;
42
43 import org.hibernate.search.jpa.FullTextEntityManager;
44 import org.hibernate.search.jpa.Search;
45
46 /***
47 * Dao to wrap/handle common JPA interactions.
48 */
49 public final class JpaDao {
50 private static JpaDao instance = null;
51 private static final ThreadLocal<EntityManager> THREAD_EM = new ThreadLocal<EntityManager>();
52 private static final Logger LOG = Logger.getLogger(JpaDao.class);
53 private final EntityManagerFactory emf;
54
55 private JpaDao(final TinLizardConfig initializer) {
56 emf = Persistence.createEntityManagerFactory("TinLizardModel", initializer.getJpaProperties());
57 }
58
59 public static synchronized void initialize(final TinLizardConfig initializer) {
60 if (instance == null) {
61 instance = new JpaDao(initializer);
62 }
63 }
64
65 public static JpaDao getInstance() {
66 return instance;
67 }
68
69 public EntityManager getEm() {
70 EntityManager em = THREAD_EM.get();
71
72 if (em == null) {
73 em = emf.createEntityManager();
74 THREAD_EM.set(em);
75 }
76
77 return em;
78 }
79
80 void closeEm() {
81 EntityManager em = THREAD_EM.get();
82
83 LOG.trace("closeEm");
84
85 if (em != null) {
86 THREAD_EM.remove();
87
88 if (em.isOpen()) {
89 em.close();
90 }
91 }
92 }
93
94 @SuppressWarnings("unchecked")
95 public void add(final Persistable obj) {
96
97 obj.setCreated(new Date());
98 obj.setCreatedBy(CurrentUser.getUsername());
99
100 EntityManager em = getEm();
101 EntityTransaction tx = em.getTransaction();
102 tx.begin();
103
104 try {
105 em.persist(obj);
106
107 tx.commit();
108 } catch (EntityExistsException e) {
109 handleError(tx, "Add Error", e);
110 } catch (Exception e) {
111 handleError(tx, "Add Error", e);
112 }
113 }
114
115 @SuppressWarnings("unchecked")
116 public void update(final Persistable obj) {
117 obj.setLastModified(new Date());
118 obj.setLastModifiedBy(CurrentUser.getUsername());
119
120 EntityManager em = getEm();
121 EntityTransaction tx = em.getTransaction();
122 tx.begin();
123
124 try {
125 em.merge(obj);
126
127 tx.commit();
128 } catch (Exception e) {
129 handleError(tx, "Update Error", e);
130 }
131 }
132
133 public void delete(final Class<?> clazz, final Integer id) {
134 EntityManager em = getEm();
135 EntityTransaction tx = em.getTransaction();
136 tx.begin();
137
138 try {
139 if (LOG.isDebugEnabled()) {
140 LOG.debug("delete(" + clazz + ", " + id + ")");
141 }
142
143 Query query = em.createQuery("delete from " + clazz.getSimpleName() + " o where o.id = :id");
144 query.setParameter("id", id);
145
146 int deleted = query.executeUpdate();
147
148 if (LOG.isDebugEnabled()) {
149 LOG.debug("Deleted " + deleted + ".");
150 }
151
152 tx.commit();
153 } catch (EntityNotFoundException e) {
154 handleInfo(tx, "Object " + clazz + "#" + id + " did not exist", e);
155 } catch (Exception e) {
156 handleError(tx, "Delete Error", e);
157 }
158 }
159
160 @SuppressWarnings("unchecked")
161 public void index(final Persistable obj) {
162 EntityManager em = getEm();
163 FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
164 EntityTransaction tx = em.getTransaction();
165 tx.begin();
166
167 try {
168 fullTextEntityManager.index(obj);
169
170 tx.commit();
171 } catch (Exception e) {
172 handleError(tx, "Index Error", e);
173 }
174 }
175
176 @SuppressWarnings("unchecked")
177 public void indexAll(final Class<?extends Persistable> clazz) {
178 EntityManager em = getEm();
179 FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
180 EntityTransaction tx = em.getTransaction();
181 tx.begin();
182
183 try {
184 fullTextEntityManager.purgeAll(clazz);
185
186 List objects = em.createQuery("select o from " + clazz.getSimpleName() + " o order by o.name").getResultList();
187
188 for (Iterator iterator = objects.iterator(); iterator.hasNext();) {
189 Object object = iterator.next();
190
191 fullTextEntityManager.index(object);
192 }
193
194 tx.commit();
195 } catch (Exception e) {
196 handleError(tx, "IndexAll Error", e);
197 }
198 }
199
200 public void handleInfo(final EntityTransaction tx, final String msg, final Exception e) {
201 rollbackTransaction(tx);
202 LOG.info(msg, e);
203 }
204
205 public void handleError(final EntityTransaction tx, final String msg, final Exception e) {
206 rollbackTransaction(tx);
207
208 closeEm();
209 throw new RuntimeException(msg, e);
210 }
211
212 private void rollbackTransaction(final EntityTransaction tx) {
213 if (tx.isActive()) {
214 tx.rollback();
215 }
216 }
217
218 @SuppressWarnings("unchecked")
219 public <T> List<T> findAll(final Class<T> clazz) {
220 List<T> rval = null;
221
222 EntityManager em = getEm();
223 EntityTransaction tx = em.getTransaction();
224 tx.begin();
225
226 try {
227 rval = em.createQuery("select o from " + clazz.getSimpleName() + " o order by o.name").getResultList();
228
229 tx.commit();
230 } catch (Exception e) {
231 handleError(tx, "FindAll Error", e);
232 }
233
234 return rval;
235 }
236
237 public <T> T findByPrimaryKey(final Class<T> clazz, final Integer id) {
238 T rval = null;
239 EntityManager em = getEm();
240 EntityTransaction tx = em.getTransaction();
241 tx.begin();
242
243 try {
244 if (LOG.isDebugEnabled()) {
245 LOG.debug("findByPrimaryKey(" + clazz + ", " + id + ")");
246 }
247
248 rval = em.find(clazz, id);
249
250 tx.commit();
251 } catch (Exception e) {
252 handleError(tx, "FindByPrimaryKey Error", e);
253 }
254
255 return rval;
256 }
257
258 public void flush() {
259 EntityManager em = getEm();
260 EntityTransaction tx = em.getTransaction();
261 tx.begin();
262
263 try {
264 em.flush();
265
266 tx.commit();
267 } catch (Exception e) {
268 handleError(tx, "Flush Error", e);
269 }
270 }
271
272 @SuppressWarnings("unchecked")
273 public <T> Collection<T> findByNamedQuery(final Class<T> clazz, final String name, final Object... params) {
274 Collection<T> rval = null;
275
276 EntityManager em = getEm();
277 EntityTransaction tx = em.getTransaction();
278 tx.begin();
279
280 try {
281 Query q = getEm().createNamedQuery(name);
282
283 for (int i = 0; i < params.length; i++) {
284 q.setParameter(i + 1, params[i]);
285 }
286
287 rval = q.getResultList();
288 tx.commit();
289 } catch (Exception e) {
290 handleError(tx, "FindByNamedQuery Error", e);
291 }
292
293 return rval;
294 }
295
296 @SuppressWarnings("unchecked")
297 public <T> T findSingleByNamedQuery(final Class<T> clazz, final String name, final Object... params) {
298 T rval = null;
299
300 EntityManager em = getEm();
301 EntityTransaction tx = em.getTransaction();
302 tx.begin();
303
304 try {
305 Query q = getEm().createNamedQuery(name);
306
307 for (int i = 0; i < params.length; i++) {
308 q.setParameter(i + 1, params[i]);
309 }
310
311 rval = (T) q.getSingleResult();
312
313 tx.commit();
314 } catch (EntityNotFoundException e) {
315 rollbackTransaction(tx);
316 closeEm();
317 } catch (NoResultException e) {
318 rollbackTransaction(tx);
319 closeEm();
320 } catch (NonUniqueResultException e) {
321 handleError(tx, "FindSingleByNamedQuery Error", e);
322 } catch (Exception e) {
323 handleError(tx, "FindSingleByNamedQuery Error", e);
324 }
325
326 return rval;
327 }
328
329 @SuppressWarnings("unchecked")
330 public <T> Collection<T> findByTextSearch(final Class<T> clazz, final String query, final String... fields) {
331 Collection<T> rval = null;
332
333 EntityManager em = getEm();
334 FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
335 EntityTransaction tx = em.getTransaction();
336 tx.begin();
337
338 try {
339
340 MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer());
341 org.apache.lucene.search.Query luceneQuery = parser.parse(query);
342
343
344 javax.persistence.Query persistenceQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, clazz);
345
346
347 rval = persistenceQuery.getResultList();
348
349 tx.commit();
350 } catch (Exception e) {
351 handleError(tx, "FindByTextSearch Error", e);
352 }
353
354 return rval;
355 }
356 }