SHOW:
|
|
- or go back to the newest paste.
1 | package org.jlego.core.dao; | |
2 | ||
3 | import java.lang.reflect.ParameterizedType; | |
4 | import java.util.Iterator; | |
5 | import java.util.List; | |
6 | import java.util.Map.Entry; | |
7 | import java.util.Set; | |
8 | - | * Base interface for all DAO classes <br/> |
8 | + | |
9 | import javax.persistence.EntityManager; | |
10 | import javax.persistence.OptimisticLockException; | |
11 | - | * <code><br/> |
11 | + | import javax.persistence.PersistenceContext; |
12 | import javax.persistence.Query; | |
13 | ||
14 | import org.jlego.core.CoreException; | |
15 | import org.jlego.core.CoreExceptionConstants; | |
16 | import org.jlego.core.dao.Criteria.CriteriaOrder; | |
17 | import org.jlego.util.EntityUtil; | |
18 | import org.springframework.dao.DataIntegrityViolationException; | |
19 | import org.springframework.transaction.annotation.Transactional; | |
20 | - | * key type |
20 | + | |
21 | /** | |
22 | - | * value/entity type |
22 | + | * Base DAO (Data Access Object). Perform routine DAO tasks such as insert, |
23 | * update, and delete <br/> | |
24 | - | public interface BaseDao<K, E> { |
24 | + | |
25 | * <br/> | |
26 | * <code> | |
27 | * public class AnotherDao extends BaseDaoImpl <Long, User> implements BaseDao {<br/> | |
28 | * <br/> | |
29 | * }<br/> | |
30 | * </code> | |
31 | * | |
32 | * @author Ali Irawan | |
33 | * @version 1.0 | |
34 | - | public void persist(E entity); |
34 | + | |
35 | * parameter as Key type | |
36 | * @param <E> | |
37 | * parameter as Entity type | |
38 | */ | |
39 | public class BaseDaoImpl<K, E> implements BaseDao<K, E> { | |
40 | ||
41 | protected Class<E> entityClass; | |
42 | protected String className; | |
43 | ||
44 | - | public E merge(K id, E entity); |
44 | + | @PersistenceContext |
45 | protected EntityManager entityManager; | |
46 | ||
47 | /** | |
48 | * Default constructor for BaseDAO | |
49 | */ | |
50 | - | * primary key that uniquely identify the object to be deleted |
50 | + | @SuppressWarnings("unchecked") |
51 | public BaseDaoImpl() { | |
52 | ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); | |
53 | this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1]; | |
54 | - | public void remove(K id); |
54 | + | String completeName = this.entityClass.getName(); |
55 | ||
56 | // Get name for the entity | |
57 | String entityName = this.entityClass.getAnnotation(javax.persistence.Entity.class).name(); | |
58 | ||
59 | if (entityName == null || entityName.equals("")) { | |
60 | ||
61 | this.className = completeName.substring(completeName.lastIndexOf('.') + 1); | |
62 | } else { | |
63 | this.className = entityName; | |
64 | - | public E findByPk(K id); |
64 | + | } |
65 | } | |
66 | ||
67 | - | * Query data with specified criteria |
67 | + | |
68 | * insert data to persistence | |
69 | * | |
70 | * @param entity | |
71 | * object to be inserted | |
72 | - | public E find(Criteria criteria); |
72 | + | |
73 | */ | |
74 | @Transactional | |
75 | public void persist(E entity) { | |
76 | try { | |
77 | entityManager.persist(entity); | |
78 | } catch (DataIntegrityViolationException e) { | |
79 | ||
80 | - | public List<E> findAll(); |
80 | + | String entityClassName = entity.getClass().getName(); |
81 | String tableName = EntityUtil.getTableName(entityClassName); | |
82 | throw new CoreException(CoreExceptionConstants.DATA_INTGR_VIOLATION, entityClassName + "(" + tableName + ")"); | |
83 | - | * Query data with specified criteria and return in a List |
83 | + | } |
84 | } | |
85 | ||
86 | /** | |
87 | - | public List<E> findAll(Criteria criteria); |
87 | + | |
88 | * | |
89 | * @param entity | |
90 | - | * Return number of data in table |
90 | + | |
91 | - | * @return count value |
91 | + | |
92 | */ | |
93 | - | public long count(); |
93 | + | @Transactional |
94 | public E merge(K id, E entity) { | |
95 | ||
96 | - | * Create a query with JPQL language |
96 | + | E entityF = findByPk(id); |
97 | - | * @param query JPQL language |
97 | + | if (entityF == null) { |
98 | - | * @return an instance of javax.persistence.Query |
98 | + | throw new CoreException(CoreExceptionConstants.ID_NOT_FOUND); |
99 | } else { | |
100 | - | public Query createQuery(String query); |
100 | + | try { |
101 | entityF = entityManager.merge(entity); | |
102 | entityManager.flush(); | |
103 | - | * Create a query with named query |
103 | + | entityManager.clear(); |
104 | - | * @param queryName name of named query (JPQL) |
104 | + | } catch (OptimisticLockException ole) { |
105 | - | * @return an instance of javax.persistence.Query |
105 | + | String entityClassName = entity.getClass().getName(); |
106 | String tableName = EntityUtil.getTableName(entityClassName); | |
107 | - | public Query createNamedQuery(String queryName); |
107 | + | throw new CoreException(CoreExceptionConstants.MERGE_FAIL_DATA_NOT_UPTODATE, entityClassName + "(" + tableName + ")"); |
108 | } | |
109 | ||
110 | - | * Create a query with using native SQL language. This is database specific. Using it will reduce portability between databases |
110 | + | return entityF; |
111 | - | * @param sqlString SQL native language based on the database used |
111 | + | } |
112 | - | * @return an instance of javax.persistence.Query |
112 | + | } |
113 | ||
114 | - | public Query createNativeQuery(String sqlString); |
114 | + | |
115 | * delete data from persistence | |
116 | * | |
117 | - | * Flush cache |
117 | + | |
118 | - | * |
118 | + | * primary key to be deleted |
119 | * @throws CoreException | |
120 | - | public void flush(); |
120 | + | |
121 | - | |
121 | + | @Transactional |
122 | public void remove(K id) { | |
123 | E entity = findByPk(id); | |
124 | if (entity == null) | |
125 | throw new CoreException(CoreExceptionConstants.ID_NOT_FOUND, (Object) null); | |
126 | else { | |
127 | try { | |
128 | entityManager.remove(entity); | |
129 | entityManager.flush(); | |
130 | entityManager.clear(); | |
131 | } catch (OptimisticLockException ole) { | |
132 | String entityClassName = entity.getClass().getName(); | |
133 | String tableName = EntityUtil.getTableName(entityClassName); | |
134 | throw new CoreException(CoreExceptionConstants.REMOVE_FAIL_DATA_NOT_UPTODATE, entityClassName + "(" + tableName + ")"); | |
135 | } | |
136 | } | |
137 | } | |
138 | ||
139 | /** | |
140 | * Search data from persistence using specified ID | |
141 | * | |
142 | * @param id | |
143 | * primary key that uniquely identify the object | |
144 | * @return return the object defined by Key, if no data match the method | |
145 | * returns null | |
146 | */ | |
147 | public E findByPk(K id) { | |
148 | return entityManager.find(entityClass, id); | |
149 | } | |
150 | ||
151 | /** | |
152 | * Query all data and return in a List | |
153 | * | |
154 | * @return list of data with specific entity type | |
155 | */ | |
156 | @SuppressWarnings("unchecked") | |
157 | public List<E> findAll() { | |
158 | List<E> allEntities = entityManager.createQuery("select e from " + className + " e").getResultList(); | |
159 | return allEntities; | |
160 | } | |
161 | ||
162 | public long count() { | |
163 | return (Long) entityManager.createQuery("select count(e) from " + className + " e").getSingleResult(); | |
164 | } | |
165 | ||
166 | /** | |
167 | * Check whether the list is empty | |
168 | * | |
169 | * @param list | |
170 | * list to be checked | |
171 | * @return true is the list is empty, neither false | |
172 | */ | |
173 | @SuppressWarnings("rawtypes") | |
174 | protected boolean isEmptyList(List list) { | |
175 | return list == null || list.size() == 0; | |
176 | } | |
177 | ||
178 | /** | |
179 | * Find using criteria | |
180 | */ | |
181 | @SuppressWarnings("unchecked") | |
182 | public E find(Criteria criteria) { | |
183 | Query query = this.criteriaToQuery(criteria); | |
184 | List<E> list = (List<E>) query.getResultList(); | |
185 | if (list.size() == 0) { | |
186 | return null; | |
187 | } | |
188 | return list.get(0); | |
189 | } | |
190 | ||
191 | /** | |
192 | * Find all using criteria | |
193 | */ | |
194 | @SuppressWarnings("unchecked") | |
195 | public List<E> findAll(Criteria criteria) { | |
196 | Query query = this.criteriaToQuery(criteria); | |
197 | List<E> list = (List<E>) query.getResultList(); | |
198 | if (list.size() == 0) { | |
199 | return null; | |
200 | } | |
201 | return list; | |
202 | } | |
203 | ||
204 | /** | |
205 | * Convert criteria to object query | |
206 | * @param criteria criteria object | |
207 | * @return query object | |
208 | */ | |
209 | private Query criteriaToQuery(Criteria criteria) { | |
210 | // example criteria: e.refNo = :refNo and e.refType = :refType | |
211 | StringBuffer sql = new StringBuffer(); | |
212 | sql.append("SELECT e FROM " + className + " e"); | |
213 | sql.append(" WHERE 1=1 AND "); | |
214 | sql.append(criteria.getCondition()); | |
215 | ||
216 | // apply order by is specified | |
217 | if (criteria.getOrdersBy().size() != 0) { | |
218 | sql.append(" ORDER BY "); | |
219 | Set<Entry<String, CriteriaOrder>> orderEntrySet = criteria.getOrdersBy().entrySet(); | |
220 | Iterator<Entry<String, CriteriaOrder>> it = orderEntrySet.iterator(); | |
221 | while (it.hasNext()) { | |
222 | Entry<String, CriteriaOrder> entry = it.next(); | |
223 | sql.append("e." + entry.getKey()); | |
224 | sql.append(" " + ((entry.getValue() == CriteriaOrder.CRITERIA_ASC) ? "ASC" : "DESC")); | |
225 | if (it.hasNext()) | |
226 | sql.append(", "); | |
227 | } | |
228 | } | |
229 | ||
230 | Query query = entityManager.createQuery(sql.toString()); | |
231 | ||
232 | // apply parameters | |
233 | Set<Entry<String, Object>> entrySet = criteria.getParameters().entrySet(); | |
234 | Iterator<Entry<String, Object>> t = entrySet.iterator(); | |
235 | while (t.hasNext()) { | |
236 | Entry<String, Object> temp = (Entry<String, Object>) t.next(); | |
237 | query.setParameter(temp.getKey(), temp.getValue()); | |
238 | } | |
239 | ||
240 | // apply startRow, the default value is 0, start from the first record | |
241 | query.setFirstResult(criteria.getStartRow()); | |
242 | ||
243 | // apply max result if specified, -1 means no max result specified | |
244 | if (criteria.getMaxResult() != -1) { | |
245 | query.setMaxResults(criteria.getMaxResult()); | |
246 | } | |
247 | return query; | |
248 | } | |
249 | ||
250 | /** | |
251 | * Create query with native query | |
252 | */ | |
253 | public Query createNativeQuery(String sqlString) { | |
254 | return entityManager.createNativeQuery(sqlString); | |
255 | } | |
256 | ||
257 | /** | |
258 | * Create query with JPQL | |
259 | */ | |
260 | public Query createQuery(String query) { | |
261 | return entityManager.createQuery(query); | |
262 | } | |
263 | ||
264 | /** | |
265 | * Create query with Named Query | |
266 | */ | |
267 | public Query createNamedQuery(String queryName) { | |
268 | return entityManager.createNamedQuery(queryName); | |
269 | } | |
270 | ||
271 | /** | |
272 | * Flush all cached to database | |
273 | */ | |
274 | public void flush() { | |
275 | entityManager.flush(); | |
276 | } | |
277 | } |