Last active
December 26, 2015 15:19
-
-
Save ggdio/7172308 to your computer and use it in GitHub Desktop.
Generic Dao for JPA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package br.com.ggdio.gist; | |
import java.io.Serializable; | |
import java.lang.reflect.ParameterizedType; | |
import java.util.ArrayList; | |
import java.util.List; | |
import javax.persistence.EntityManager; | |
import javax.persistence.EntityManagerFactory; | |
import javax.persistence.EntityNotFoundException; | |
import javax.persistence.PersistenceException; | |
import javax.persistence.Query; | |
import javax.persistence.TypedQuery; | |
import javax.persistence.criteria.CriteriaBuilder; | |
import javax.persistence.criteria.CriteriaQuery; | |
import javax.persistence.criteria.Root; | |
import org.apache.log4j.Logger; | |
public abstract class Dao<T> { | |
private static final Logger log = Logger.getLogger(Dao.class); | |
private final EntityManager em; | |
public Dao(EntityManagerFactory factory) { | |
this.em = factory.createEntityManager(); | |
} | |
protected EntityManager getEntityManager() { | |
return em; | |
} | |
@SuppressWarnings("unchecked") | |
private Class<T> getClazz() { | |
return (Class<T>) ((ParameterizedType) getClass() | |
.getGenericSuperclass()).getActualTypeArguments()[0]; | |
} | |
/** | |
* Retrieves an entity by its id | |
* | |
* @param id | |
* - identifier of the current entity | |
* @return An entity found by the identifier | |
*/ | |
public T get(Serializable id) { | |
T entity = null; | |
Class<T> clazz = getClazz(); | |
try { | |
begin(); | |
CriteriaBuilder cb = em.getCriteriaBuilder(); | |
CriteriaQuery<T> c = cb.createQuery(clazz); | |
Root<T> obj = c.from(clazz); | |
c.where(cb.equal(obj.get("id"), cb.parameter(clazz, "id"))); | |
TypedQuery<T> query = em.createQuery(c); | |
query.setParameter("id", id); | |
entity = query.getSingleResult(); | |
commit(); | |
} catch (Exception e) { | |
rollback(); | |
String msg = "The delete of entity '" | |
+ entity.getClass().getSimpleName() | |
+ "' caused an exception"; | |
log.error(msg, e); | |
throw new DaoException(msg, e); | |
} finally { | |
close(); | |
} | |
if (entity == null) | |
throw new EntityNotFoundException("Unnable to find the entity '" | |
+ clazz.getSimpleName() | |
+ "' with an identifier equals to '" + id + "'"); | |
return entity; | |
} | |
/** | |
* Identify all the occurencies of the current entity on the database, | |
* limited by a first result index and the max results to be collected | |
* | |
* @param firstResult | |
* - The first row index | |
* @param maxResults | |
* - Maximum number of rows to be collected | |
* @return List of values of the current entity | |
*/ | |
@SuppressWarnings("unchecked") | |
public List<T> listAll(Integer firstResult, Integer maxResults) { | |
List<T> entities = new ArrayList<T>(); | |
try { | |
begin(); | |
CriteriaQuery<T> criteria = em.getCriteriaBuilder().createQuery( | |
getClazz()); | |
criteria.multiselect(criteria.from(getClass())); | |
Query query = em.createQuery(criteria); | |
if (firstResult > 0) | |
query.setFirstResult(firstResult); | |
if (maxResults > 0) | |
query.setMaxResults(maxResults); | |
entities.addAll(query.getResultList()); | |
commit(); | |
} catch (Exception e) { | |
rollback(); | |
String msg = "An unexpected error occured while trying to list the entity '" | |
+ getClazz().getSimpleName() + "'"; | |
log.error(msg, e); | |
throw new DaoException(msg, e); | |
} finally { | |
close(); | |
} | |
return entities; | |
} | |
/** | |
* Identify all the occurencies of the current entity on the database, | |
* limited a max number of results to be collected | |
* | |
* @param maxResults | |
* - Maximum number of rows to be collected | |
* @return List of values of the current entity | |
*/ | |
public List<T> listAll(Integer maxResults) { | |
return listAll(0, maxResults); | |
} | |
/** | |
* Collect all the occurencies of the entity on the database | |
* | |
* @return List of values of the current entity | |
*/ | |
public List<T> listAll() { | |
return listAll(0, 0); | |
} | |
/** | |
* Execute hql query on the database | |
* | |
* @param hql | |
* - The query to be executed | |
* @param firstResult | |
* - The first row index | |
* @param maxResults | |
* - Maximum number of rows to be collected | |
* @return | |
*/ | |
@SuppressWarnings("unchecked") | |
public List<T> hqlQuery(String hql, Integer firstResult, Integer maxResults) { | |
List<T> entities = null; | |
try { | |
begin(); | |
Query query = em.createQuery(hql); | |
if (firstResult > 0) | |
query.setFirstResult(firstResult); | |
if (maxResults > 0) | |
query.setMaxResults(maxResults); | |
entities = query.getResultList(); | |
commit(); | |
} catch (Exception e) { | |
rollback(); | |
String msg = "An unexpected error occured while executing the following HQL: '" | |
+ hql | |
+ "' with an row limit of '" | |
+ maxResults | |
+ "' and first result '" + firstResult + "'"; | |
log.error(msg, e); | |
throw new DaoException(msg, e); | |
} finally { | |
close(); | |
} | |
if (entities.size() == 0) | |
throw new EntityNotFoundException( | |
"The execution of the following hql query, didn't brought any results: " | |
+ hql); | |
return entities; | |
} | |
/** | |
* Execute hql query on the database | |
* | |
* @param hql | |
* - The query to be executed | |
* @param maxResults | |
* - Maximum number of rows to be collected | |
* @return | |
*/ | |
public List<T> hqlQuery(String hql, Integer maxResults) { | |
return hqlQuery(hql, 0, maxResults); | |
} | |
/** | |
* Execute hql query on the database | |
* | |
* @param hql | |
* - The query to be executed | |
* @return | |
*/ | |
public List<T> hqlQuery(String hql) { | |
return hqlQuery(hql, 0, 0); | |
} | |
/** | |
* Initialize the session and the transaction | |
*/ | |
protected void begin() { | |
if (!isTransactionActive()) { | |
try { | |
em.getTransaction().begin(); | |
} catch (PersistenceException e) { | |
log.warn("Couldn't open and begin the transaction", e); | |
} | |
} | |
} | |
/** | |
* Execute commit operation | |
*/ | |
protected void commit() { | |
if (isTransactionActive()) { | |
try { | |
em.getTransaction().commit(); | |
em.clear(); | |
} catch (PersistenceException e) { | |
log.warn("Couldn't commit the current transaction", e); | |
} | |
} | |
} | |
/** | |
* Execute rollback operation | |
*/ | |
protected void rollback() { | |
if (isTransactionActive()) { | |
try { | |
em.getTransaction().rollback(); | |
em.clear(); | |
} catch (PersistenceException e) { | |
log.warn("Couldn't rollback the current transaction", e); | |
} | |
} | |
} | |
protected void close() { | |
if (em != null) { | |
try { | |
if (isTransactionActive()) | |
rollback(); | |
em.clear(); | |
em.close(); | |
} catch (PersistenceException e) { | |
log.warn("Couldn't close the entity-manager", e); | |
} | |
} | |
} | |
/** | |
* Identify if the current transaction is active or not | |
* | |
* @return True - if its active | |
* <p> | |
* False - if its not active | |
*/ | |
protected Boolean isTransactionActive() { | |
return em.getTransaction() != null && em.getTransaction().isActive(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment