package org.opennaas.core.persistence;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.apache.openjpa.persistence.criteria.OpenJPACriteriaBuilder;
import org.springframework.beans.factory.annotation.Required;
/**
* JPA implementation of the GenericRepository. Note that this implementation also expects OpenJPA as JPA implementation. That's because we use the
* Criteria API.
*
* @author Jurgen Lust
*
* @param <T>
* The persistent type
* @param <ID>
* The primary key type
*/
public class GenericJpaRepository<T, ID extends Serializable>
implements GenericRepository<T, ID>
{
private final Class<T> entityClass;
private EntityManager entityManager;
public GenericJpaRepository(final Class<T> entityClass) {
this.entityClass = entityClass;
}
@SuppressWarnings("unchecked")
public GenericJpaRepository() {
entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
private OpenJPACriteriaBuilder getCriteriaBuilder() {
return (OpenJPACriteriaBuilder) entityManager.getCriteriaBuilder();
}
@Override
public int countAll() {
OpenJPACriteriaBuilder builder = getCriteriaBuilder();
CriteriaQuery<Long> query = builder.createQuery(Long.class);
Root<T> entities = query.from(entityClass);
query.select(builder.count(entities));
return (int) (long) entityManager.createQuery(query).getSingleResult();
}
@Override
public int countByExample(final T exampleInstance) {
OpenJPACriteriaBuilder builder = getCriteriaBuilder();
CriteriaQuery<Long> query = builder.createQuery(Long.class);
Root<T> entities = query.from(entityClass);
query.where(builder.qbe(entities, exampleInstance));
query.select(builder.count(entities));
return (int) (long) entityManager.createQuery(query).getSingleResult();
}
@Override
public List<T> findAll() {
OpenJPACriteriaBuilder builder = getCriteriaBuilder();
CriteriaQuery<T> query = builder.createQuery(entityClass);
query.from(entityClass);
return entityManager.createQuery(query).getResultList();
}
@Override
public List<T> findByExample(final T exampleInstance) {
OpenJPACriteriaBuilder builder = getCriteriaBuilder();
CriteriaQuery<T> query = builder.createQuery(entityClass);
Root<T> entities = query.from(entityClass);
query.where(builder.qbe(entities, exampleInstance));
return entityManager.createQuery(query).getResultList();
}
@Override
public T findById(final ID id) {
return entityManager.find(entityClass, id);
}
@Override
public List<T> findByNamedQuery(final String name, Object... params) {
TypedQuery<T> query = entityManager.createNamedQuery(name, entityClass);
for (int i = 0; i < params.length; i++) {
query.setParameter(i + 1, params[i]);
}
return query.getResultList();
}
@Override
public List<T> findByNamedQueryAndNamedParams(final String name,
final Map<String, ? extends Object> params)
{
TypedQuery<T> query = entityManager.createNamedQuery(name, entityClass);
for (Map.Entry<String, ? extends Object> param : params.entrySet()) {
query.setParameter(param.getKey(), param.getValue());
}
return query.getResultList();
}
/**
* @see be.bzbit.framework.domain.repository.GenericRepository#getEntityClass()
*/
@Override
public Class<T> getEntityClass() {
return entityClass;
}
@Override
public void delete(T entity) {
entityManager.remove(entity);
}
@Override
public T save(T entity) {
return entityManager.merge(entity);
}
@Required
@PersistenceContext
public void setEntityManager(final EntityManager entityManager) {
this.entityManager = entityManager;
}
public EntityManager getEntityManager() {
return entityManager;
}
}