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

com.tvd12.ezydata.jpa.repository.EzyJpaRepository Maven / Gradle / Ivy

There is a newer version: 1.2.9
Show newest version
package com.tvd12.ezydata.jpa.repository;

import com.tvd12.ezydata.database.EzyDatabaseContext;
import com.tvd12.ezydata.database.EzyDatabaseContextAware;
import com.tvd12.ezydata.database.EzyDatabaseRepository;
import com.tvd12.ezydata.jpa.EzyJpaDatabaseContext;
import com.tvd12.ezydata.jpa.reflect.EzyJpaIdProxy;
import com.tvd12.ezyfox.exception.UnimplementedOperationException;
import com.tvd12.ezyfox.reflect.EzyClass;
import com.tvd12.ezyfox.reflect.EzyGenerics;
import com.tvd12.ezyfox.util.EzyLoggable;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@SuppressWarnings({"rawtypes", "unchecked"})
public class EzyJpaRepository
    extends EzyLoggable
    implements EzyDatabaseRepository, EzyDatabaseContextAware {

    protected final Class entityType;
    protected final EzyClass entityClass;
    protected final EzyJpaIdProxy idProxy;
    protected EzyJpaDatabaseContext databaseContext;
    protected static final Object[] NO_PARAMETERS = new Object[0];

    public EzyJpaRepository() {
        this.entityType = getEntityType();
        this.entityClass = new EzyClass(entityType);
        this.idProxy = new EzyJpaIdProxy(entityClass);
    }

    @Override
    public void setDatabaseContext(EzyDatabaseContext context) {
        this.databaseContext = (EzyJpaDatabaseContext) context;
    }

    @Override
    public void save(E entity) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            EntityTransaction transaction = entityManager.getTransaction();
            transaction.begin();
            try {
                E result = entityManager.merge(entity);
                transaction.commit();
                idProxy.setId(result, entity);
            } catch (Exception e) {
                transaction.rollback();
                throw e;
            }
        } finally {
            entityManager.close();
        }
    }

    @Override
    public void save(Iterable entities) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            EntityTransaction transaction = entityManager.getTransaction();
            transaction.begin();
            try {
                List results = new ArrayList<>();
                for (E entity : entities) {
                    E result = entityManager.merge(entity);
                    results.add(result);
                }
                transaction.commit();
                int i = 0;
                for (E entity : entities) {
                    idProxy.setId(results.get(i++), entity);
                }
            } catch (Exception e) {
                transaction.rollback();
                throw e;
            }
        } finally {
            entityManager.close();
        }
    }

    @Override
    public E findById(I id) {
        return findByField("id", id);
    }

    @Override
    public E findByField(String field, Object value) {
        String queryString = "select e from " +
            entityType.getName() + " e " +
            "where e." + field + " = ?0";
        EntityManager entityManager = databaseContext.createEntityManager();
        List resultList;
        try {
            Query query = entityManager.createQuery(queryString);
            query.setParameter(0, value);
            query.setMaxResults(1);
            resultList = query.getResultList();
        } finally {
            entityManager.close();
        }
        Object entity = resultList.isEmpty() ? null : resultList.get(0);
        return (E) entity;
    }

    @Override
    public List findListByField(String field, Object value, int skip, int limit) {
        String queryString = "select e from " +
            entityType.getName() + " e " +
            "where e." + field + " = ?0";
        return findListByQueryString(queryString, new Object[]{value}, skip, limit);
    }

    @Override
    public List findListByField(String field, Object value) {
        String queryString = "select e from " +
            entityType.getName() + " e " +
            "where e." + field + " = ?0";
        return findListByQueryString(queryString, new Object[]{value});
    }

    protected E findByQueryString(String queryString, Object[] parameters) {
        EntityManager entityManager = databaseContext.createEntityManager();
        List resultList;
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            query.setMaxResults(1);
            resultList = query.getResultList();
        } finally {
            entityManager.close();
        }
        Object entity = resultList.isEmpty() ? null : resultList.get(0);
        return (E) entity;
    }

    @Override
    public List findListByIds(Collection ids) {
        String queryString = "select e from " +
            entityType.getName() + " e " +
            "where e.id in ?0";
        return findListByQueryString(queryString, new Object[]{ids});
    }

    protected List findListByQueryString(String queryString, Object[] parameters) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            return query.getResultList();
        } finally {
            entityManager.close();
        }
    }

    protected List findListByQueryString(
        String queryString,
        Object[] parameters,
        int skip,
        int limit
    ) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            query.setFirstResult(skip);
            query.setMaxResults(limit);
            return query.getResultList();
        } finally {
            entityManager.close();
        }
    }

    protected List findListByQueryString(
        String queryString,
        Map parameters,
        int skip,
        int limit
    ) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            query.setFirstResult(skip);
            query.setMaxResults(limit);
            return query.getResultList();
        } finally {
            entityManager.close();
        }
    }

    protected  List fetchListByQueryString(
        String queryString,
        Object[] parameters,
        Class resultType,
        int skip,
        int limit
    ) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            query.setFirstResult(skip);
            query.setMaxResults(limit);
            return databaseContext.deserializeResultList(
                query.getResultList(),
                resultType
            );
        } finally {
            entityManager.close();
        }
    }

    protected  List fetchListByQueryString(
        String queryString,
        Map parameters,
        Class resultType,
        int skip,
        int limit
    ) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            query.setFirstResult(skip);
            query.setMaxResults(limit);
            return databaseContext.deserializeResultList(
                query.getResultList(),
                resultType
            );
        } finally {
            entityManager.close();
        }
    }

    @Override
    public List findAll() {
        String queryString = "select e from " +
            entityType.getName() + " e ";
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = entityManager.createQuery(queryString);
            return query.getResultList();
        } finally {
            entityManager.close();
        }
    }

    @Override
    public List findAll(int skip, int limit) {
        String queryString = "select e from " +
            entityType.getName() + " e ";
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = entityManager.createQuery(queryString);
            query.setFirstResult(skip);
            query.setMaxResults(limit);
            return query.getResultList();
        } finally {
            entityManager.close();
        }
    }

    @Override
    public boolean containsById(I id) {
        return containsByField("id", id);
    }

    @Override
    public boolean containsByField(String field, Object value) {
        String queryString = "select e." + field + " from " +
            entityType.getName() + " e " +
            "where e." + field + " = ?0";
        EntityManager entityManager = databaseContext.createEntityManager();
        List resultList;
        try {
            Query query = entityManager.createQuery(queryString);
            query.setParameter(0, value);
            query.setMaxResults(1);
            resultList = query.getResultList();
        } finally {
            entityManager.close();
        }
        return resultList.size() > 0;
    }

    @Override
    public int deleteAll() {
        String queryString = "delete from " +
            entityType.getName() + " e ";
        return deleteByQueryString(queryString, NO_PARAMETERS);
    }

    @Override
    public void delete(I id) {
        String queryString = "delete from " +
            entityType.getName() + " e " +
            "where e.id = ?0";
        deleteByQueryString(queryString, new Object[]{id});
    }

    @Override
    public int deleteByIds(Collection ids) {
        String queryString = "delete from " +
            entityType.getName() + " e " +
            "where e.id in ?0";
        return deleteByQueryString(queryString, new Object[]{ids});
    }

    protected int deleteByQueryString(String queryString, Object[] parameters) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            EntityTransaction transaction = entityManager.getTransaction();
            transaction.begin();
            try {
                int deletedRows = query.executeUpdate();
                transaction.commit();
                return deletedRows;
            } catch (Exception e) {
                transaction.rollback();
                throw e;
            }
        } finally {
            entityManager.close();
        }
    }

    @Override
    public long count() {
        String queryString = "select count(e.id) from " +
            entityType.getName() + " e ";
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = entityManager.createQuery(queryString);
            return (long) query.getSingleResult();
        } finally {
            entityManager.close();
        }
    }

    protected long countByQueryString(String queryString, Object[] parameters) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            return (long) query.getSingleResult();
        } finally {
            entityManager.close();
        }
    }

    protected long countByQueryString(String queryString, Map parameters) {
        EntityManager entityManager = databaseContext.createEntityManager();
        try {
            Query query = createQuery(entityManager, queryString, parameters);
            return (long) query.getSingleResult();
        } finally {
            entityManager.close();
        }
    }

    protected Query createQuery(
        EntityManager entityManager,
        String queryString,
        Object[] parameters
    ) {
        Query query = entityManager.createQuery(queryString);
        for (int i = 0; i < parameters.length; ++i) {
            query.setParameter(i, parameters[i]);
        }
        return query;
    }

    protected Query createQuery(
        EntityManager entityManager,
        String queryString,
        Map parameters
    ) {
        Query query = entityManager.createQuery(queryString);
        for (String paramName : parameters.keySet()) {
            Object paramValue = parameters.get(paramName);
            if (paramValue != null) {
                query.setParameter(paramName, paramValue);
            }
        }
        return query;
    }

    protected Class getEntityType() {
        try {
            Type genericSuperclass = getClass().getGenericSuperclass();
            Class[] genericArgs = EzyGenerics.getTwoGenericClassArguments(genericSuperclass);
            return genericArgs[1];
        } catch (Exception e) {
            throw new UnimplementedOperationException(
                "class " + getClass().getName()
                    + " hasn't implemented method 'getEntityType'",
                e
            );
        }
    }

}