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 | } |