package PersistenceManager.Interface;
import EnvironmentPluginAPI.Exceptions.TechnicalException;
import PersistenceManager.Implementation.PersistenceManagerComponent;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: N3trunner
* Date: 13.05.12
* Time: 13:04
* To change this template use File | Settings | File Templates.
*/
public abstract class AbstractDao<T> {
// ------------------------------ FIELDS ------------------------------
protected static Object daoLock = new Object();
protected boolean isUnitTest;
protected Class<T> entityClass;
// --------------------------- CONSTRUCTORS ---------------------------
/**
* Initializes a new Abstract Dao. An abstract dao is responsible for providing administration functionality for one
* entity class. There may be more than one Abstract Dao for an entity. All Daos for a certain entity type will share
* the same EntityManager.
*
* @param entityClass The type of the entity, this dao will be responsible for.
*/
public AbstractDao(Class<T> entityClass) throws TechnicalException {
this(entityClass, false);
}
/**
* Initializes a new Abstract Dao. An abstract dao is responsible for providing administration functionality for one
* entity class. There may be more than one Abstract Dao for an entity. All Daos for a certain entity type will share
* the same EntityManager.
*
* @param entityClass The type of the entity, this dao will be responsible for.
* @param isUnitTest Indicates if the entitymanager should use the database for unit tests.
*/
public AbstractDao(Class<T> entityClass, boolean isUnitTest) throws TechnicalException {
this.isUnitTest = isUnitTest;
this.entityClass = entityClass;
getEntityManager();
}
// --------------------- GETTER / SETTER METHODS ---------------------
// private EntityManager entityManager;
/**
* Provides access to the Entity Manager for the entityClass this dao is responsible for.
* All daos that have the same entityClass also share the same EntityManager.
*
* @return The EntityManager used for connecting to the database.
*/
protected synchronized EntityManager getEntityManager() throws TechnicalException {
EntityManager entityManager;
if (isUnitTest) {
entityManager = PersistenceManagerComponent.getEntityManagerForUnitTesting(entityClass);
} else {
entityManager = PersistenceManagerComponent.getEntityManager(entityClass);
}
return entityManager;
}
// -------------------------- PUBLIC METHODS --------------------------
/**
* Returns the number of entities contained in the database.
*
* @return The number of entities that are contained in the database.
*/
public int count() throws TechnicalException {
synchronized (daoLock) {
getEntityManager().getTransaction().begin();
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
getEntityManager().getTransaction().commit();
return ((Long) q.getSingleResult()).intValue();
}
}
/**
* Saves the given entity in the database.
*
* @param entity The entity that will be saved.
*/
public void create(T entity) throws TechnicalException {
synchronized (daoLock) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(entity);
entityManager.getTransaction().commit();
}
}
/**
* Updates the given entity in the database.
*
* @param entity
*/
public void edit(T entity) throws TechnicalException {
synchronized (daoLock) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
entityManager.merge(entity);
entityManager.getTransaction().commit();
}
}
/**
* Executes a typed query on the database.
*
* @param query The query that will be executed.
* @return The results-list of the query.
*/
public List<T> executeQuery(TypedQuery<T> query) {
synchronized (daoLock) {
return query.getResultList();
}
}
/**
* Executes a typed query on the database.
*
* @param queryString The query that will be executed.
* @return The results-list of the query.
*/
public List<T> executeQuery(String queryString) throws TechnicalException {
synchronized (daoLock) {
TypedQuery<T> query = getEntityManager().createQuery(
queryString, entityClass);
return query.getResultList();
}
}
/**
* Finds and returns a entity by its id.
*
* @param id The id of the entity that should be searched for.
* @return The entity, if one with the given id was found, otherwise null.
*/
public T find(Object id) throws TechnicalException {
synchronized (daoLock) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
T foundEntity = entityManager.find(entityClass, id);
entityManager.getTransaction().commit();
return foundEntity;
}
}
/**
* Finds all entites of T that are contained in the database.
*
* @return A list of all entities of T.
*/
public List<T> findAll() throws TechnicalException {
synchronized (daoLock) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
javax.persistence.criteria.CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
List<T> foundEntities = entityManager.createQuery(cq).getResultList();
entityManager.getTransaction().commit();
return foundEntities;
}
}
public List<T> findRange(int[] range) throws TechnicalException {
synchronized (daoLock) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
javax.persistence.criteria.CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.Query q = entityManager.createQuery(cq);
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
entityManager.getTransaction().commit();
return q.getResultList();
}
}
/**
* Gets a criteria builder for this abstract Dao.
*
* @return
*/
public CriteriaBuilder getCriteriaBuilder() throws TechnicalException {
synchronized (daoLock) {
return getEntityManager().getCriteriaBuilder();
}
}
/**
* Removes the given entity from the database.
*
* @param entity The entity that will be removed.
*/
public void remove(T entity) throws TechnicalException {
synchronized (daoLock) {
EntityManager entityManager = getEntityManager();
entityManager.getTransaction().begin();
entityManager.remove(getEntityManager().merge(entity));
entityManager.getTransaction().commit();
}
}
}