package org.genedb.db.dao;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.stereotype.Repository;
import java.util.List;
public class BaseDao {
private static final Logger logger = Logger.getLogger(BaseDao.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
return SessionFactoryUtils.getSession(sessionFactory, false);
}
protected <T> List<T> performQuery(Class<T> typeToken, String queryString) {
return performQuery(typeToken, queryString, new String[0], new Object[0]);
}
protected <T> List<T> performQuery(Class<T> typeToken, String queryString, String parameterName, Object parameterValue) {
return performQuery(typeToken, queryString, new String[] {parameterName}, new Object[] {parameterValue});
}
protected <T> List<T> performQuery(Class<T> typeToken, String queryString, String[] parameterNames, Object[] parameterValues) {
Query query = createQuery(queryString, parameterNames, parameterValues);
@SuppressWarnings("unchecked") // Checked at runtime below
List<T> list = query.list();
if (!list.isEmpty() && !typeToken.isInstance(list.get(0))) {
throw new RuntimeException(String.format("Returned value is of type '%s', expected '%s'",
list.get(0).getClass(), typeToken));
}
return list;
}
protected Query createQuery(String queryString, String[] parameterNames,
Object[] parameterValues) {
if (parameterNames.length != parameterValues.length) {
throw new IllegalArgumentException("Number of parameter values must equal number of parameter names");
}
Query query = getSession().createQuery(queryString);
for (int i = 0; i < parameterNames.length; i++) {
query.setParameter(parameterNames[i], parameterValues[i]);
}
return query;
}
/**
* Save the object to the database (at the end of the current transaction,
* or depending upon flush mode). This method is defined in all the DAOs.
* It's recommended to call it through an appropriate one eg SequenceDao
* for Feature
*
* @param o The object to store
*/
public void persist(Object o) {
getSession().persist(o);
}
/**
* Either save(Object) or update(Object) the given instance, depending upon resolution
* of the unsaved-value checks (see the Hibernate manual for discussion of unsaved-value checking).
* <p>
* This operation cascades to associated instances if the association is mapped with cascade="save-update".
* This method is defined in all the DAOs.
*
* @param o The object to save or update
*/
public void saveOrUpdate(Object o) {
getSession().saveOrUpdate(o);
}
/**
* Copy the state of the given object onto the persistent object with the same identifier.
* If there is no persistent instance currently associated with the session, it will be loaded.
* Return the persistent instance. If the given instance is unsaved, save a copy of and return
* it as a newly persistent instance. The given instance does not become associated with the session.
* This operation cascades to associated instances if the association is mapped with cascade="merge".
* <p>
* This method is defined in all the DAOs.
*
* @param o The object to merge
*/
public Object merge(Object o) {
return getSession().merge(o);
}
/**
* Remove the object from the database (at the end of the current
* transaction, or depending upon flush mode). This method is defined in all
* the DAOs.
*
* @param o The object to delete
*/
public void delete(Object o) {
getSession().delete(o);
}
/**
* Flush the session.
*/
public void flush() {
getSession().flush();
}
/**
* Returns the first element of the given list, or null if the list is
* empty. If the list has more than one element, logs a warning before
* returning.
*
* The intention is that this should be called by data access methods that
* expect a single result. The args parameters should consist alternately of
* names and values, indicating the query parameters used.
*
* @param <T>
* @param list The result list
* @param args The query parameters (included in the log message if list
* contains more than one element)
* @return
*/
protected <T> T firstFromList(List<T> list, Object... args) {
if (list == null) {
logger.warn("Got called with null list");
return null;
}
if (list.size() == 0) {
return null;
}
if (list.size() > 1) {
// Log warning
StringBuilder sb = new StringBuilder();
boolean varName = true;
boolean first = true;
if (args != null && args.length > 0) {
for (Object object : args) {
if (!first && varName) {
sb.append("', ");
}
sb.append(object);
if (varName) {
sb.append("='");
}
varName = !varName;
first = false;
}
sb.append("'");
}
logger.warn("Expected one result, but got '" + list.size() + "' results in list ('"
+ sb + "')");
}
return list.get(0);
}
}