1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.hack23.cia.service.data.impl;
20
21 import java.io.Serializable;
22 import java.util.List;
23
24 import javax.annotation.PostConstruct;
25 import javax.persistence.EntityManager;
26 import javax.persistence.PersistenceContext;
27 import javax.persistence.TypedQuery;
28 import javax.persistence.criteria.CriteriaBuilder;
29 import javax.persistence.criteria.CriteriaQuery;
30 import javax.persistence.criteria.Join;
31 import javax.persistence.criteria.Path;
32 import javax.persistence.criteria.Predicate;
33 import javax.persistence.criteria.Root;
34 import javax.persistence.metamodel.Metamodel;
35 import javax.persistence.metamodel.SingularAttribute;
36
37 import org.hibernate.CacheMode;
38 import org.hibernate.search.jpa.FullTextEntityManager;
39 import org.hibernate.search.jpa.Search;
40
41 import com.hack23.cia.service.data.api.AbstractGenericDAO;
42 import com.hack23.cia.service.data.impl.util.LoadHelper;
43
44
45
46
47
48
49
50
51
52
53 abstract class AbstractGenericDAOImpl<T extends Serializable, I extends Serializable>
54 implements AbstractGenericDAO<T, I> {
55
56
57 @PersistenceContext(name = "ciaPersistenceUnit")
58 private EntityManager entityManager;
59
60
61 private CriteriaBuilder criteriaBuilder;
62
63
64 private Metamodel metamodel;
65
66
67 private final Class<T> persistentClass;
68
69
70
71
72
73
74
75 protected AbstractGenericDAOImpl(final Class<T> persistentClass) {
76 this.persistentClass = persistentClass;
77 }
78
79
80
81
82
83
84
85
86
87 protected final void addCacheHints(final TypedQuery<?> typedQuery, final String comment) {
88 typedQuery.setHint("org.hibernate.cacheMode", CacheMode.NORMAL);
89 typedQuery.setHint("org.hibernate.cacheable", Boolean.TRUE);
90 typedQuery.setHint("org.hibernate.comment", comment);
91 }
92
93 @Override
94 public final void delete(final T entity) {
95 getEntityManager().remove(entity);
96
97 }
98
99 @Override
100 public final T findFirstByProperty(final SingularAttribute<T, ? extends Object> property, final Object value) {
101 final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
102 final Root<T> root = criteriaQuery.from(getPersistentClass());
103 criteriaQuery.select(root);
104 final Predicate condition = criteriaBuilder.equal(root.get(property), value);
105 criteriaQuery.where(condition);
106 final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
107 addCacheHints(typedQuery, "findFirstByProperty");
108
109 final List<T> resultList = typedQuery.getResultList();
110
111 if (resultList.isEmpty()) {
112 return null;
113 } else {
114 return LoadHelper.recursiveInitialize(resultList.get(0));
115 }
116 }
117
118 @Override
119 public final List<T> findListByProperty(final Object[] values,
120 final SingularAttribute<T, ? extends Object>... properties) {
121 final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(persistentClass);
122 final Root<T> root = criteriaQuery.from(persistentClass);
123 criteriaQuery.select(root);
124
125 final Object value = values[0];
126 final SingularAttribute<T, ? extends Object> property = properties[0];
127 Predicate condition;
128
129 condition = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root, value, property);
130
131 if (values.length > 1) {
132 for (int i = 1; i < properties.length; i++) {
133 final SingularAttribute<T, ? extends Object> property2 = properties[i];
134 final Object value2 = values[i];
135 final Predicate condition2 = QueryHelper.equalsIgnoreCaseIfStringPredicate(criteriaBuilder, root,
136 value2, property2);
137
138 condition = criteriaBuilder.and(condition, condition2);
139 }
140 }
141
142 criteriaQuery.where(condition);
143
144 final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
145 addCacheHints(typedQuery, "findListByProperty");
146
147 return typedQuery.getResultList();
148 }
149
150 @Override
151 public final List<T> findListByProperty(final SingularAttribute<T, ? extends Object> property, final Object value) {
152 final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
153 final Root<T> root = criteriaQuery.from(getPersistentClass());
154 criteriaQuery.select(root);
155 final Predicate condition = criteriaBuilder.equal(root.get(property), value);
156 criteriaQuery.where(condition);
157 final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
158 addCacheHints(typedQuery, "findListByProperty");
159 return typedQuery.getResultList();
160 }
161
162 @Override
163 public <V> List<T> findListByEmbeddedProperty(final SingularAttribute<T, V> property, final Class<V> clazz2,
164 final SingularAttribute<V, ? extends Object> property2, final Object value) {
165 return findOrderedByPropertyListByEmbeddedProperty(property,clazz2,property2,value,null);
166
167 }
168
169 @Override
170 public <V> List<T> findOrderedByPropertyListByEmbeddedProperty(final SingularAttribute<T, V> property,
171 final Class<V> clazz2, final SingularAttribute<V, ? extends Object> property2, final Object value,
172 final SingularAttribute<T, ? extends Object> orderByProperty) {
173 final CriteriaQuery<T> criteriaQuery = criteriaBuilder
174 .createQuery(persistentClass);
175 final Root<T> root = criteriaQuery.from(persistentClass);
176 criteriaQuery.select(root);
177
178 if (orderByProperty != null) {
179 criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderByProperty)));
180 }
181
182
183 final Join<T, V> join = root.join(property);
184
185 final Path<? extends Object> path = join.get(property2);
186
187 final Predicate condition = criteriaBuilder.equal(path, value);
188
189 criteriaQuery.where(condition);
190
191 final TypedQuery<T> typedQuery = entityManager
192 .createQuery(criteriaQuery);
193
194 addCacheHints(typedQuery, "findListByEmbeddedProperty." + persistentClass.getSimpleName());
195
196
197 return typedQuery.getResultList();
198 }
199
200
201 @Override
202 public final List<T> getAll() {
203 return getAllOrderBy(null);
204 }
205
206 @Override
207 public final List<T> getAllOrderBy(final SingularAttribute<T, ? extends Object> orderBy) {
208 return getPageOrderBy(null, null, orderBy);
209 }
210
211
212
213
214
215
216 public final CriteriaBuilder getCriteriaBuilder() {
217 return criteriaBuilder;
218 }
219
220
221
222
223
224
225 protected final EntityManager getEntityManager() {
226 return entityManager;
227 }
228
229
230
231
232
233
234 protected final FullTextEntityManager getFullTextEntityManager() {
235 return Search.getFullTextEntityManager(getEntityManager());
236 }
237
238
239
240
241
242
243 protected final Metamodel getMetamodel() {
244 return metamodel;
245 }
246
247 @Override
248 public final List<T> getPage(int pageNr, int resultPerPage) {
249 return getPageOrderBy(pageNr, resultPerPage, null);
250 }
251
252 @Override
253 public final List<T> getPageOrderBy(int pageNr, int resultPerPage, final SingularAttribute<T, ? extends Object> orderBy) {
254 return getPageOrderBy(Integer.valueOf(pageNr), Integer.valueOf(resultPerPage), orderBy);
255 }
256
257 private List<T> getPageOrderBy(Integer pageNr, Integer resultPerPage,
258 final SingularAttribute<T, ? extends Object> orderBy) {
259 final CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getPersistentClass());
260 final Root<T> root = criteriaQuery.from(getPersistentClass());
261
262 criteriaQuery.select(root);
263
264 if (orderBy != null) {
265 criteriaQuery.orderBy(criteriaBuilder.desc(root.get(orderBy)));
266 }
267
268 final TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
269 addCacheHints(typedQuery, "getAll");
270
271 if (pageNr != null && resultPerPage != null) {
272 typedQuery.setFirstResult((pageNr - 1) * resultPerPage);
273 typedQuery.setMaxResults(resultPerPage);
274
275 }
276
277 return typedQuery.getResultList();
278
279 }
280
281
282
283
284
285
286 public final Class<T> getPersistentClass() {
287 return this.persistentClass;
288 }
289
290 @Override
291 public final Long getSize() {
292 final CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
293 countQuery.select(criteriaBuilder.count(countQuery.from(persistentClass)));
294 return getEntityManager().createQuery(countQuery).getSingleResult();
295 }
296
297
298
299
300 @PostConstruct
301 private void init() {
302 this.criteriaBuilder = getEntityManager().getCriteriaBuilder();
303 this.metamodel = getEntityManager().getMetamodel();
304 }
305
306 @Override
307 public final T load(final I id) {
308 return LoadHelper.recursiveInitialize(getEntityManager().find(getPersistentClass(), id));
309 }
310
311 @Override
312 public final T merge(final T entity) {
313 return getEntityManager().merge(entity);
314 }
315
316 @Override
317 public final void persist(final List<T> list) {
318 for (final T t : list) {
319 getEntityManager().persist(t);
320 }
321 }
322
323 @Override
324 public final void persist(final T entity) {
325 getEntityManager().persist(entity);
326 }
327
328 @Override
329 public final List<T> search(final String searchExpression, final Integer maxResults, final String... fields) {
330 return getFullTextEntityManager().createFullTextQuery(
331 getFullTextEntityManager().getSearchFactory().buildQueryBuilder().forEntity(persistentClass).get()
332 .keyword().wildcard().onFields(fields).matching(searchExpression).createQuery(),
333 persistentClass).setMaxResults(maxResults).getResultList();
334 }
335
336 }