package com.aggrepoint.dao; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; import java.util.List; import javax.persistence.EntityManager; import org.hibernate.Criteria; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.ReplicationMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.DetachedCriteria; import org.springframework.dao.DataAccessException; /** * * @author Jiangming Yang (yangjm@gmail.com) * */ public class DaoBaseMethod<T> implements DaoMethod<T> { Class<T> clz; static Object[][] methods = { { 101, "create", new Class[] { null }, DaoService.class }, { 102, "createOrUpdate", new Class[] { null }, DaoService.class }, { 103, "find", new Class[] { Serializable.class }, DaoService.class }, { 104, "find", new Class[] {}, DaoService.class }, { 105, "update", new Class[] { null }, DaoService.class }, { 106, "delete", new Class[] { null }, DaoService.class }, { 107, "delete", new Class[] { Collection.class }, DaoService.class }, { 108, "evict", new Class[] { null }, DaoService.class }, { 1, "clear", new Class[] {}, HibernateDao.class }, { 2, "contains", new Class[] { Object.class }, HibernateDao.class }, { 3, "evict", new Class[] { Object.class }, HibernateDao.class }, { 4, "find", new Class[] { String.class }, HibernateDao.class }, { 5, "find", new Class[] { String.class, Object.class }, HibernateDao.class }, { 6, "find", new Class[] { String.class, Object[].class }, HibernateDao.class }, { 7, "findByCriteria", new Class[] { DetachedCriteria.class }, HibernateDao.class }, { 8, "findByCriteria", new Class[] { DetachedCriteria.class, int.class, int.class }, HibernateDao.class }, { 9, "findByNamedParam", new Class[] { String.class, String.class, Object.class }, HibernateDao.class }, { 10, "findByNamedParam", new Class[] { String.class, String[].class, Object[].class }, HibernateDao.class }, { 11, "findByNamedQuery", new Class[] { String.class }, HibernateDao.class }, { 12, "findByNamedQuery", new Class[] { String.class, Object.class }, HibernateDao.class }, { 13, "findByNamedQuery", new Class[] { String.class, Object[].class }, HibernateDao.class }, { 14, "findByNamedQueryAndNamedParam", new Class[] { String.class, String.class, Object.class }, HibernateDao.class }, { 15, "findByNamedQueryAndNamedParam", new Class[] { String.class, String[].class, Object[].class }, HibernateDao.class }, { 16, "flush", new Class[] {}, HibernateDao.class }, { 17, "load", new Class[] { Object.class, Serializable.class }, HibernateDao.class }, { 18, "merge", new Class[] { Object.class }, HibernateDao.class }, { 19, "persist", new Class[] { Object.class }, HibernateDao.class }, { 20, "refresh", new Class[] { Object.class }, HibernateDao.class }, { 21, "replicate", new Class[] { Object.class, ReplicationMode.class }, HibernateDao.class } }; EntityManager entityManager; SessionFactory sessionFactory; int methodId; private Session getSession() { if (entityManager != null) return entityManager.unwrap(Session.class); if (sessionFactory != null) return sessionFactory.getCurrentSession(); return null; } public DaoBaseMethod(Class<T> clz, Method method, EntityManager manager, SessionFactory factory) { this.clz = clz; this.entityManager = manager; this.sessionFactory = factory; for (Object[] m : methods) { if (!method.getName().equals(m[1])) continue; if (!method.getDeclaringClass().equals(m[3])) continue; Class<?>[] ptypes = method.getParameterTypes(); if (!(ptypes.length == ((Class[]) m[2]).length)) continue; boolean notMatch = false; for (int i = 0; i < ptypes.length; i++) if (!(((Class[]) m[2])[i] == null || ptypes[i] .equals(((Class[]) m[2])[i]))) { notMatch = true; break; } if (!notMatch) { methodId = (Integer) m[0]; return; } } throw new IllegalArgumentException("Unable to match method '" + method + "' defined in interface '" + method.getDeclaringClass().getName() + "'."); } @SuppressWarnings("unchecked") public List<T> find(final String queryString, final Object... values) throws DataAccessException { Query queryObject = getSession().createQuery(queryString); // SessionFactoryUtils.applyTransactionTimeout(queryObject, factory); if (values != null) { for (int i = 0; i < values.length; i++) { queryObject.setParameter(i, values[i]); } } return queryObject.list(); } @SuppressWarnings("unchecked") public List<T> findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults) throws DataAccessException { Criteria executableCriteria = criteria .getExecutableCriteria(getSession()); // SessionFactoryUtils.applyTransactionTimeout(executableCriteria, // factory); if (firstResult >= 0) { executableCriteria.setFirstResult(firstResult); } if (maxResults > 0) { executableCriteria.setMaxResults(maxResults); } return executableCriteria.list(); } static void applyNamedParameterToQuery(Query queryObject, String paramName, Object value) throws HibernateException { if (value instanceof Collection) { queryObject.setParameterList(paramName, (Collection<?>) value); } else if (value instanceof Object[]) { queryObject.setParameterList(paramName, (Object[]) value); } else { queryObject.setParameter(paramName, value); } } @SuppressWarnings("unchecked") public List<T> findByNamedParam(final String queryString, final String[] paramNames, final Object[] values) throws DataAccessException { Query queryObject = getSession().createQuery(queryString); // SessionFactoryUtils.applyTransactionTimeout(queryObject, factory); if (values != null) { for (int i = 0; i < values.length; i++) applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); } return queryObject.list(); } @SuppressWarnings("unchecked") public List<T> findByNamedQuery(final String queryName, final Object... values) throws DataAccessException { Query queryObject = getSession().getNamedQuery(queryName); // SessionFactoryUtils.applyTransactionTimeout(queryObject, factory); if (values != null) { for (int i = 0; i < values.length; i++) { queryObject.setParameter(i, values[i]); } } return queryObject.list(); } @SuppressWarnings("unchecked") public List<T> findByNamedQueryAndNamedParam(final String queryName, final String[] paramNames, final Object[] values) throws DataAccessException { Query queryObject = getSession().getNamedQuery(queryName); // SessionFactoryUtils.applyTransactionTimeout(queryObject, factory); if (values != null) { for (int i = 0; i < values.length; i++) { applyNamedParameterToQuery(queryObject, paramNames[i], values[i]); } } return queryObject.list(); } @SuppressWarnings("unchecked") public Object invoke(Object proxy, Method method, Object[] args) { switch (methodId) { case 101: return getSession().save(args[0]); case 102: getSession().saveOrUpdate(args[0]); return null; case 103: return getSession().get(clz, (Serializable) args[0]); case 104: Criteria criteria = getSession().createCriteria(clz); criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // SessionFactoryUtils.applyTransactionTimeout(criteria, factory); return criteria.list(); case 105: getSession().update(args[0]); return null; case 106: getSession().delete(args[0]); return null; case 107: Session session = getSession(); for (T t : (Collection<T>) args[0]) session.delete(t); return null; case 108: getSession().evict(args[0]); return null; case 1: getSession().clear(); return null; case 2: return getSession().contains(args[0]); case 3: getSession().evict(args[0]); return null; case 4: return find((String) args[0], (Object[]) null); case 5: return find((String) args[0], new Object[] { args[1] }); case 6: return find((String) args[0], (Object[]) args[1]); case 7: return findByCriteria((DetachedCriteria) args[0], -1, -1); case 8: return findByCriteria((DetachedCriteria) args[0], (Integer) args[1], (Integer) args[2]); case 9: return findByNamedParam((String) args[0], new String[] { (String) args[1] }, new Object[] { args[2] }); case 10: return findByNamedParam((String) args[0], (String[]) args[1], (Object[]) args[2]); case 11: return findByNamedQuery((String) args[0], (Object[]) null); case 12: return findByNamedQuery((String) args[0], new Object[] { args[1] }); case 13: return findByNamedQuery((String) args[0], (Object[]) args[1]); case 14: return findByNamedQueryAndNamedParam((String) args[0], new String[] { (String) args[1] }, new Object[] { args[2] }); case 15: return findByNamedQueryAndNamedParam((String) args[0], (String[]) args[1], (Object[]) args[2]); case 16: getSession().flush(); return null; case 17: getSession().load(args[0], (Serializable) args[1]); return null; case 18: return getSession().merge(args[0]); case 19: getSession().persist(args[0]); return null; case 20: getSession().refresh(args[0]); return null; case 21: getSession().replicate(args[0], (ReplicationMode) args[1]); return null; } return null; } @Override public boolean match(Object[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { return true; } }