All Downloads are FREE. Search and download functionalities are using the official Maven repository.

springdao.support.AbstractSpringDao Maven / Gradle / Ivy

package springdao.support;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.PersistenceUnit;
import javax.persistence.PersistenceUnitUtil;
import javax.persistence.Query;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.dao.support.DaoSupport;
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import springdao.DaoRepository;

/**
 *
 * @author Kent Yeh
 * @param 
 */
public abstract class AbstractSpringDao extends DaoSupport implements DaoRepository {

    private static final Logger log = LogManager.getLogger(AbstractSpringDao.class);
    private EntityManagerFactory emf;
    private EntityManager em;

    @Override
    protected void checkDaoConfig() throws IllegalArgumentException {
        if (this.emf == null) {
            throw new IllegalArgumentException("'EntityManagerFactory' is required");
        }
        if (this.em == null) {
            throw new IllegalArgumentException("'EntityManager' is required");
        }
    }

    public EntityManagerFactory getEntityManagerFactory() {
        return emf;
    }

    @PersistenceUnit
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }

    public EntityManager getEntityManager() {
        return em;
    }

    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }

    LockModeType getLockMode(String lockMode) {
        try {
            return LockModeType.valueOf(lockMode);
        } catch (RuntimeException ex) {
            return LockModeType.NONE;
        }
    }

    @Override
    public E instanate() throws InstantiationException, IllegalAccessException {
        try {
            return getClazz().newInstance();
        } catch (InstantiationException | IllegalAccessException ex) {
            log.error("Instanate error", ex);
            throw ex;
        }
    }

    protected RuntimeException convertException(Exception e) {
        if (e instanceof RuntimeException) {
            RuntimeException res = EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible((RuntimeException) e);
            return res == null ? (RuntimeException) e : res;
        } else {
            return new RuntimeException(e.getMessage(), e);
        }
    }

    @Override
    public void clear() {
        try {
            em.clear();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public boolean contains(Object entity) {
        try {
            return em.contains(entity);
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E findByPrimaryKey(Serializable primaryKey) {
        try {
            return em.find(getClazz(), primaryKey);
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E findByPrimaryKey(Serializable primaryKey, String lockMode) {
        try {
            return em.find(getClazz(), primaryKey, getLockMode(lockMode));
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E findByPrimaryKey(Serializable primaryKey, Map properties) {
        try {
            return em.find(getClazz(), primaryKey, properties);
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E findByPrimaryKey(Serializable primaryKey, String lockMode, Map properties) {
        try {
            return em.find(getClazz(), primaryKey, getLockMode(lockMode), properties);
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E save(E entity) {
        return persist(entity);
    }

    @Override
    public Collection save(Collection entities) {
        try {
            ArrayList result = new ArrayList<>(entities.size());
            for (E entity : entities) {
                result.add(persist(entity));
            }
            em.flush();
            return result;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E persist(E entity) {
        try {
            em.persist(entity);
            em.flush();
            return entity;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E update(E entity) {
        return merge(entity);
    }
    
    @Override
    public Collection update(Collection entities) {
        return merge(entities);
    }

    @Override
    public E merge(E entity) {
        try {
            E result = em.merge(entity);
            em.flush();
            return result;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public Collection merge(Collection entities) {
        try {
            ArrayList result = new ArrayList<>(entities.size());
            for (E entity : entities) {
                result.add(em.merge(entity));
            }
            em.flush();
            return result;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    /**
     * Before using this method, look at
     * saveOrUpdate
     * vs. merge.
     *
     * @param entity
     * @return merged entity
     */
    @Override
    public E saveOrUpdate(E entity) {
        return contains(entity) ? merge(entity) : emf.getPersistenceUnitUtil().getIdentifier(entity) == null ? persist(entity) : merge(entity);
    }

    @Override
    public Collection saveOrUpdate(Collection entities) {
        try {
            ArrayList result = new ArrayList<>(entities.size());
            for (E entity : entities) {
                result.add(saveOrUpdate(entity));
            }
            em.flush();
            return result;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public void delete(Serializable primaryKey) {
        try {
            Object entity = em.find(getClazz(), primaryKey);
            if (entity != null) {
                em.remove(entity);
                em.flush();
            }
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public void delete(Serializable primaryKey, String lockMode) {
        try {
            Object entity = em.find(getClazz(), primaryKey,getLockMode(lockMode));
            if (entity != null) {
                em.remove(entity);
                em.flush();
            }
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public void delete(Collection primaryKeys) {
        try {
            for (Serializable pk : primaryKeys) {
                Object entity = em.find(getClazz(), pk);
                if (entity != null) {
                    em.remove(entity);
                }
            }
            em.flush();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E remove(E entity) {
        entity = merge(entity);
        try {
            em.remove(entity);
            em.flush();
            return entity;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E remove(E entity, String lockMode) {
        Object pk = emf.getPersistenceUnitUtil().getIdentifier(entity);
        if (pk == null) {
            return null;
        } else {
            entity = em.find(getClazz(), pk, getLockMode(lockMode));
            if (entity == null) {
                return null;
            } else {
                em.remove(entity);
                em.flush();
                return entity;
            }
        }
    }

    @Override
    public Collection remove(Collection entities) {
        try {
            ArrayList result = new ArrayList<>(entities.size());
            for (E entity : entities) {
                entity = merge(entity);
                em.remove(entity);
                result.add(entity);
            }
            em.flush();
            return result;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E lock(E entity, String lockMode) {
        try {
            em.lock(entity, getLockMode(lockMode));
            return entity;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E refresh(E entity) {
        try {
            if(em.contains(entity))
                em.refresh(entity);
            else{
                Object pk = emf.getPersistenceUnitUtil().getIdentifier(entity);
                return em.find(getClazz(), pk);
            }
            return entity;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E refresh(E entity, String lockMode) {
        try {
            if (em.contains(entity)) {
                em.refresh(entity, getLockMode(lockMode));
            } else {
                Object pk = emf.getPersistenceUnitUtil().getIdentifier(entity);
                return em.find(getClazz(), pk, getLockMode(lockMode));
            }
            return entity;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }
    
    @Override
    public int sqlUpdate(String sql) {
        try {
            return em.createNativeQuery(sql).executeUpdate();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public int sqlUpdate(String sql, Object... parameters) {
        try {
            int i = 0;
            Query query = em.createNativeQuery(sql);
            if (parameters != null && parameters.length > 0) {
                for (Object paramter : parameters) {
                    query.setParameter(++i, paramter);
                }
            }
            return query.executeUpdate();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public int sqlUpdate(String sql, Map parameters) {
        try {
            int i = 0;
            Query query = em.createNativeQuery(sql);
            if (parameters != null && !parameters.isEmpty()) {
                for(Map.Entry entry:parameters.entrySet()){
                    query.setParameter(entry.getKey(), entry.getValue());
                }
            }
            return query.executeUpdate();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }
    
    @Override
    public List sqlUpdate(List sqls) {
        try {
            List res = new ArrayList<>(sqls.size());
            for (String sql : sqls){
                res.add(em.createNativeQuery(sql).executeUpdate());
            }
            return res;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public int bulkUpdate(String QL) {
        try {
            return em.createQuery(QL).executeUpdate();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public List bulkUpdate(List QLs) {
        try {
            List result = new ArrayList<>();
            for (String ql : QLs) {
                result.add(em.createQuery(ql).executeUpdate());
            }
            return result;
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public int bulkUpdate(String QL, Object... parameters) {
        try {
            Query query = em.createQuery(QL);
            int i = 0;
            if (parameters != null && parameters.length > 0) {
                for (Object paramter : parameters) {
                    query.setParameter(++i, paramter);
                }
            }
            return query.executeUpdate();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public int bulkUpdate(String QL, Map parameters) {
        try {
            Query query = em.createQuery(QL);
            int i = 0;
            if (parameters != null && !parameters.isEmpty()) {
                for(Map.Entry entry:parameters.entrySet()){
                    query.setParameter(entry.getKey(), entry.getValue());
                }
            }
            return query.executeUpdate();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public String $e() {
        return getEntityName();
    }

    @Override
    public String getEntityName() {
        return getClazz().getName();
    }

    @Override
    public String $a() {
        return getAliasName();
    }

    @Override
    public String $ea() {
        return getEntityName() + " AS " + getAliasName();
    }

    @Override
    public String getAliasName() {
        return AliasHelper.$a(getClazz());
    }

    protected List findList(Query query) {
        try {
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    protected List findList(Query query, Object... parameters) {
        try {
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++) {
                    query.setParameter(i + 1, parameters[i]);
                }
            }
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    protected List findList(Query query, Map parameters) {
        try {
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && !parameters.isEmpty()) {
                for(Map.Entry entry:parameters.entrySet()){
                    query.setParameter(entry.getKey(), entry.getValue());
                }
            }
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public List findByCriteria(String qlCriteria) {
        return findList(em.createQuery(JpqlHelper.get().select($a()).
                from($ea()).$(qlCriteria).ql()));
    }

    @Override
    public List findByCriteria(String qlCriteria, Object... parameters) {
        return findList(em.createQuery(JpqlHelper.get().select($a()).
                from($ea()).$(qlCriteria).ql()), parameters);
    }

    @Override
    public List findByCriteria(String qlCriteria, Map parameters) {
        return findList(em.createQuery(JpqlHelper.get().select($a()).from($ea())
                .$(qlCriteria).ql()), parameters);
    }

    @Override
    public List findByCriteria(String qlCriteria, int startPageNo, int pageSize, Object... parameters) {
        if ((startPageNo < 1) || (pageSize < 1)) {
            return parameters == null || parameters.length == 0 ? findByCriteria(qlCriteria) : findByCriteria(qlCriteria, parameters);
        } else if (parameters == null || parameters.length == 0) {
            return findByCriteria(qlCriteria, startPageNo, pageSize);
        } else {
            return findList(em.createQuery(JpqlHelper.get().select($a()).from($ea()).$(qlCriteria).ql()).
                    setFirstResult((startPageNo - 1) * pageSize).setMaxResults(pageSize), parameters);
        }
    }

    @Override
    public List findByCriteria(String qlCriteria, int startPageNo, int pageSize, Map parameters) {
        if ((startPageNo < 1) || (pageSize < 1)) {
            return parameters == null || parameters.isEmpty() ? findByCriteria(qlCriteria) : findByCriteria(qlCriteria, parameters);
        } else if (parameters == null || parameters.isEmpty()) {
            return findByCriteria(qlCriteria, startPageNo, pageSize);
        } else {
            return findList(em.createQuery(JpqlHelper.get().select($a()).from($ea()).$(qlCriteria).ql())
                    .setFirstResult((startPageNo - 1) * pageSize).setMaxResults(pageSize), parameters);
        }
    }

    @Override
    public List findByCriteria(String qlCriteria, int startPageNo, int pageSize) {
        if ((startPageNo < 1) || (pageSize < 1)) {
            return findByCriteria(qlCriteria);
        } else {
            return findList(em.createQuery(JpqlHelper.get().select($a()).from($ea()).$(qlCriteria).ql()).setFirstResult((startPageNo - 1) * pageSize).setMaxResults(pageSize));
        }
    }

    @Override
    public List findBySQLQuery(String sql) {
        return findList(em.createNativeQuery(sql, getClazz()));
    }

    @Override
    public List findBySQLQuery(String sql, Object... parameters) {
        return findList(em.createNativeQuery(sql, getClazz()), parameters);
    }

    @Override
    public List findBySQLQuery(String sql, Map parameters) {
        return findList(em.createNativeQuery(sql, getClazz()), parameters);
    }

    @Override
    public  T findUniqueByQL(String QL) {
        try {
            Query query = em.createQuery(QL);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            return (T) query.getSingleResult();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public  T findUniqueByQL(String QL, Object... parameters) {
        try {
            Query query = em.createQuery(QL);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++) {
                    query.setParameter(i + 1, parameters[i]);
                }
            }
            return (T) query.getSingleResult();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public  T findUniqueByQL(String QL, Map parameters) {
        try {
            Query query = em.createQuery(QL);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && !parameters.isEmpty()) {
                for(Map.Entry entry:parameters.entrySet()){
                    query.setParameter(entry.getKey(), entry.getValue());
                }
            }
            return (T) query.getSingleResult();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public  List findListByQL(String QL) {
        try {
            Query query = em.createQuery(QL);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            return query.getResultList();
        } catch (RuntimeException e) {
            log.error(e.getMessage(), e);
            throw convertException(e);
        }
    }

    @Override
    public  List findListByQL(String QL, Object... parameters) {
        try {
            Query query = em.createQuery(QL);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++) {
                    query.setParameter(i + 1, parameters[i]);
                }
            }
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public  List findListByQL(String QL, Map parameters) {
        try {
            Query query = em.createQuery(QL);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && !parameters.isEmpty()) {
                for(Map.Entry entry:parameters.entrySet()){
                    query.setParameter(entry.getKey(), entry.getValue());
                }
            }
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public List findByNamedQuery(String name) {
        return findList(em.createNamedQuery(name, getClazz()));
    }

    @Override
    public List findByNamedQuery(String name, Object... parameters) {
        return findList(em.createNamedQuery(name, getClazz()), parameters);
    }

    @Override
    public List findByNamedQuery(String name, Map parameters) {
        return findList(em.createNamedQuery(name, getClazz()), parameters);
    }

    @Override
    public  List findListByNamedQuery(String name) {
        try {
            Query query = em.createNamedQuery(name);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public  List findListByNamedQuery(String name, Object... parameters) {
        try {
            Query query = em.createNamedQuery(name);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++) {
                    query.setParameter(i + 1, parameters[i]);
                }
            }
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public  List findListByNamedQuery(String name, Map parameters) {
        try {
            Query query = em.createNamedQuery(name);
            EntityManagerFactoryUtils.applyTransactionTimeout(query, getEntityManagerFactory());
            if (parameters != null && !parameters.isEmpty()) {
                for(Map.Entry entry:parameters.entrySet()){
                    query.setParameter(entry.getKey(), entry.getValue());
                }
            }
            return query.getResultList();
        } catch (RuntimeException e) {
            throw convertException(e);
        }
    }

    @Override
    public E initLazyCollection(E entity, final String collectionFieldName) {
        final AtomicBoolean found = new AtomicBoolean(false);
        final String methodName = collectionFieldName.matches("^[a-z][A-Z]") ? collectionFieldName : collectionFieldName.length() > 1
                ? collectionFieldName.substring(0, 1).toUpperCase() + collectionFieldName.substring(1) : collectionFieldName.toUpperCase();
        final Object obj = entity;
        final EntityManager fem = em;
        try {
            ReflectionUtils.doWithMethods(getClazz(),
                    new ReflectionUtils.MethodCallback() {
                        @Override
                        public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                            try {
                                Method setter = obj.getClass().getMethod("s" + method.getName().substring(1), method.getReturnType());
                                PersistenceUnitUtil puu = fem.getEntityManagerFactory().getPersistenceUnitUtil();
                                if (!puu.isLoaded(obj, collectionFieldName)) {
                                    E reattach = (E) fem.merge(obj);
//                                    E reattach = (E) em.find(obj.getClass(), puu.getIdentifier(obj));
                                    Object fieldObj = method.invoke(reattach, new Object[]{});
                                    ((Collection) fieldObj).size();
                                    setter.invoke(obj, fieldObj);
                                }
                            } catch (NoSuchMethodException ex) {
                                throw new PersistenceException("Setter " + getClazz().getSimpleName() + ".set" + methodName + "(...) not found.", ex);
                            } catch (InvocationTargetException ex) {
                                throw new PersistenceException("Could not fetch Collection from " + getClazz().getSimpleName() + "." + method.getName(), ex);
                            }
                        }
                    },
                    new ReflectionUtils.MethodFilter() {
                        @Override
                        public boolean matches(Method method) {
                            if (found.get()) {
                                return false;
                            } else {
                                found.set(method.getName().equals("get" + methodName) && method.getParameterTypes().length == 0
                                        && ClassUtils.isAssignable(Collection.class, method.getReturnType()));
                                return found.get();
                            }
                        }
                    });
            return (E) obj;
        } catch (IllegalArgumentException e) {
            throw convertException(e);
        } finally {
            EntityManagerFactoryUtils.closeEntityManager(fem);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy