Skip to content

Instantly share code, notes, and snippets.

@ggdio
Last active December 26, 2015 15:19
Show Gist options
  • Save ggdio/7172308 to your computer and use it in GitHub Desktop.
Save ggdio/7172308 to your computer and use it in GitHub Desktop.
Generic Dao for JPA
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