View difference between Paste ID: NqJ9um6U and i33UwrTb
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
}