/*
* Copyright (C) 2009 - 2010 Interactive Media Management
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package dk.i2m.converge.ejb.services;
import dk.i2m.converge.core.DataNotFoundException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
/**
* Stateless session bean providing a data access object service for accessing
* entities.
*
* @author Allan Lykke Christensen
*/
@EJB(name = "UserServiceBeanRef", beanInterface = UserServiceLocal.class)
@Stateless
public class DaoServiceBean implements DaoServiceLocal {
@PersistenceContext(unitName = "converge-ejbPU")
private EntityManager em;
/**
* Stores a given object in the data store.
*
* @param <T>
* Type of entity to store
* @param t
* Entity to store
* @return Object stored in the data store.
*/
@Override
public <T> T create(T t) {
this.em.persist(t);
this.em.flush();
this.em.refresh(t);
return t;
}
public void commit() {
this.em.getTransaction().commit();
}
/**
* Finds a given entity in the data store.
*
* @param <T>
* Type of entity
* @param type
* Type of entity
* @param id
* Unique identifier of the entity
* @return Entity matching the unique identifier
* @throws DataNotFoundException
* If no match could be found
*/
@Override
public <T> T findById(Class<T> type, Object id) throws DataNotFoundException {
if (id == null) {
throw new DataNotFoundException("null is not a valid primary key for " + type.getName());
}
T entity = this.em.find(type, id);
if (entity == null) {
throw new DataNotFoundException(type.getName() + " with ID " + id + " not found");
}
return entity;
}
/**
* Remove a given object from the data store.
*
* @param type
* Type of object
* @param id
* Unique identifier of the object
*/
@Override
public void delete(Class type, Object id) {
if (id == null) {
return;
}
Object obj = this.em.find(type, id);
if (obj != null) {
this.em.remove(obj);
}
}
/** {@inheritDoc } */
@Override
public <T> T update(T t) {
return this.em.merge(t);
}
/** {@inheritDoc } */
@Override
public int executeQuery(String namedQueryName, QueryBuilder qb) {
Set<Entry<String, Object>> rawParameters = qb.parameters().entrySet();
Query query = this.em.createNamedQuery(namedQueryName);
for (Entry<String, Object> entry : rawParameters) {
query.setParameter(entry.getKey(), entry.getValue());
}
return query.executeUpdate();
}
/** {@inheritDoc } */
@Override
public int executeQuery(String namedQueryName) {
Query query = this.em.createNamedQuery(namedQueryName);
return query.executeUpdate();
}
/**
* Finds a {@link List} of entity returned by the given named query.
*
* @param namedQueryName
* Name of the query
* @return {@link List} of entities returned by the given query
*/
@Override
public List findWithNamedQuery(String namedQueryName) {
return this.em.createNamedQuery(namedQueryName).getResultList();
}
/**
* Finds a {@link List} of entity returned by the given named query.
*
* @param namedQueryName
* Name of the query
* @param parameters
* Parameters of the query
* @return {@link List} of entities returned by the given query
*/
@Override
public List findWithNamedQuery(String namedQueryName, Map<String, Object> parameters) {
return findWithNamedQuery(namedQueryName, parameters, 0);
}
/** {@inheritDoc } */
@Override
public <T> T findObjectWithNamedQuery(Class<T> type, String namedQueryName, Map<String, Object> parameters) throws DataNotFoundException {
@SuppressWarnings("unchecked")
List<T> results = findWithNamedQuery(namedQueryName, parameters, 0);
if (results.isEmpty()) {
throw new DataNotFoundException("Not found");
} else {
return results.iterator().next();
}
}
/** {@inheritDoc } */
@Override
public <T> T findObjectWithNamedQuery(Class<T> type, String namedQueryName, QueryBuilder queryBuilder) throws DataNotFoundException {
return findObjectWithNamedQuery(type, namedQueryName, queryBuilder.parameters());
}
/**
* Finds a {@link List} of entity returned by the given named query.
*
* @param queryName
* Name of the query
* @param resultLimit
* Maximum number of results
* @return {@link List} of entities returned by the given query
*/
@Override
public List findWithNamedQuery(String queryName, int resultLimit) {
return this.em.createNamedQuery(queryName).
setMaxResults(resultLimit).
getResultList();
}
/**
* Finds a {@link List} of entity returned by the given named query.
*
* @param namedQueryName
* Name of the query
* @param parameters
* Parameters of the query
* @param resultLimit
* Maximum number of results
* @return {@link List} of entities returned by the given query
*/
@Override
public List findWithNamedQuery(String namedQueryName, Map<String, Object> parameters, int resultLimit) {
Set<Entry<String, Object>> rawParameters = parameters.entrySet();
Query query = this.em.createNamedQuery(namedQueryName);
if (resultLimit > 0) {
query.setMaxResults(resultLimit);
}
for (Entry<String, Object> entry : rawParameters) {
query.setParameter(entry.getKey(), entry.getValue());
}
return query.getResultList();
}
/**
* Finds a {@link List} of entity returned by the given named query.
*
* @param namedQueryName Name of the query
* @param parameters Parameters of the query
* @param start First record of the result set
* @param resultLimit Maximum number of results
* @return {@link List} of entities returned by the given query
*/
@Override
public List findWithNamedQuery(String namedQueryName, Map<String, Object> parameters, int start, int resultLimit) {
Set<Entry<String, Object>> rawParameters = parameters.entrySet();
Query query = this.em.createNamedQuery(namedQueryName);
if (start > -1) {
query.setFirstResult(start);
}
query.setFirstResult(start);
if (resultLimit > 0) {
query.setMaxResults(resultLimit);
}
for (Entry<String, Object> entry : rawParameters) {
query.setParameter(entry.getKey(), entry.getValue());
}
return query.getResultList();
}
/**
* Finds a {@link List} of entities returned from the given native SQL
* query.
*
* @param sql
* Native SQL query
* @param type
* Type of entity
* @return {@link List} of entities returned from the given native SQL query
*/
@Override
public List findByNativeQuery(String sql, Class type) {
return this.em.createNativeQuery(sql, type).getResultList();
}
/**
* Finds all the entities of a given type.
*
* @param <T>
* Type of entity
* @param type
* Type of entity
* @return {@link List} of all entities of the given type
*/
@Override
public <T> List<T> findAll(Class<T> type) {
return new LinkedList(this.em.createQuery("SELECT o from " + type.getSimpleName() + " AS o").getResultList());
}
@Override
public <T> List<T> findAll(Class<T> type, String orderBy, boolean asc) {
String direction = asc ? "ASC" : "DESC";
return new LinkedList(this.em.createQuery("SELECT o from " + type.getSimpleName() + " AS o ORDER BY o." + orderBy + " " + direction).getResultList());
}
@Override
public <T> List<T> findAll(Class<T> type, int start, int resultLimit) {
return new LinkedList(this.em.createQuery("SELECT o from " + type.getSimpleName() + " AS o").setFirstResult(start).setMaxResults(resultLimit).getResultList());
}
@Override
public <T> List<T> findAll(Class<T> type, int start, int resultLimit, String orderBy, boolean asc) {
String direction = asc ? "ASC" : "DESC";
return new LinkedList(this.em.createQuery("SELECT o from " + type.getSimpleName() + " AS o ORDER BY o." + orderBy + " " + direction).setFirstResult(start).setMaxResults(resultLimit).getResultList());
}
@Override
public <T> Number count(Class<T> type, String field) {
return (Number)this.em.createQuery("SELECT COUNT(o." + field + ") from " + type.getSimpleName() + " o").getSingleResult();
}
}