org.businessmanager.dao.GenericDaoImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.businessmanager.dao.GenericDaoImpl.java

Source

/*******************************************************************************
 * Copyright 2012 Christian Ternes and Thorsten Volland
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package org.businessmanager.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;

import org.businessmanager.dao.em.FilteredEntityManager;
import org.businessmanager.domain.AbstractEntity;
import org.businessmanager.domain.ModificationType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/**
 *
 * Generic DAO-Implementation to support standard DAO methods (CRUD).
 *
 * @author Christian Ternes
 * @param <T> an entity class
 */
public abstract class GenericDaoImpl<T extends AbstractEntity> implements GenericDao<T> {

    @Autowired
    @Qualifier("filteredEntityManager")
    private EntityManager entityManager;

    @Autowired
    @Qualifier("TransactionManager")
    private PlatformTransactionManager txManager;

    public abstract Class<T> getPersistenceClass();

    @Override
    public T save(T domainObject) {
        entityManager.persist(domainObject);
        return domainObject;
    }

    @Override
    public T update(T domainObject) {
        entityManager.merge(domainObject);
        return domainObject;
    }

    @Override
    public void remove(T domainObject) {
        entityManager.merge(domainObject);
    }

    @Override
    public void removePhysical(T domainObject) {
        T entity = entityManager.merge(domainObject);
        entityManager.remove(entity);
    }

    @Override
    public List<T> findAll(SingularAttribute<T, ?> orderAttribute, boolean orderAsc) {
        return findAll(orderAttribute, orderAsc, -1, -1);
    }

    @Override
    public List<T> findAll(SingularAttribute<T, ?> orderAttribute, boolean orderAsc, int firstResult,
            int maxResults) {
        return findAll(orderAttribute, orderAsc, firstResult, maxResults, null);
    }

    @Override
    public List<T> findAll(SingularAttribute<T, ?> orderAttribute, boolean orderAsc, int firstResult,
            int maxResults, Map<SingularAttribute<T, ?>, Object> filterAttributes) {
        return findAll(orderAttribute, orderAsc, firstResult, maxResults, filterAttributes, false);
    }

    @Override
    public List<T> findAll(SingularAttribute<T, ?> orderAttribute, boolean orderAsc, int firstResult,
            int maxResults, Map<SingularAttribute<T, ?>, Object> filterAttributes, boolean enableLikeSearch) {
        CriteriaBuilder queryBuilder = entityManager.getCriteriaBuilder();

        CriteriaQuery<T> criteriaQuery = queryBuilder.createQuery(getPersistenceClass());
        Root<T> rootQuery = criteriaQuery.from(getPersistenceClass());

        CriteriaQuery<T> select = criteriaQuery.select(rootQuery);

        List<Predicate> predicateList = createFilterList(filterAttributes, enableLikeSearch, queryBuilder,
                rootQuery);
        select.where(predicateList.toArray(new Predicate[0]));

        if (orderAsc) {
            criteriaQuery.orderBy(queryBuilder.asc(rootQuery.get(orderAttribute)));
        } else {
            criteriaQuery.orderBy(queryBuilder.desc(rootQuery.get(orderAttribute)));
        }

        TypedQuery<T> typedQuery = entityManager.createQuery(criteriaQuery);

        if (firstResult != -1) {
            typedQuery.setFirstResult(firstResult);
        }
        if (maxResults != -1) {
            typedQuery.setMaxResults(maxResults);
        }

        return typedQuery.getResultList();
    }

    @Override
    public T findById(Long id) {
        if (id == null) {
            return null;
        }

        //filter out deleted entities
        T entityFromDb = entityManager.find(getPersistenceClass(), id);
        if (entityFromDb instanceof AbstractEntity) {
            if (ModificationType.DELETE.equals(entityFromDb.getModificationType())) {
                return null;
            }
        }

        return entityFromDb;
    }

    @Override
    public List<T> findByAttribute(SingularAttribute<T, ?> key, Object value) {
        Map<SingularAttribute<T, ?>, Object> anAttributeMap = new HashMap<SingularAttribute<T, ?>, Object>();
        anAttributeMap.put(key, value);

        return findByAttributes(anAttributeMap);
    }

    @Override
    public List<T> findByAttributes(Map<SingularAttribute<T, ?>, Object> theAttributes) {
        CriteriaBuilder queryBuilder = entityManager.getCriteriaBuilder();

        CriteriaQuery<T> criteriaQuery = queryBuilder.createQuery(getPersistenceClass());
        Root<T> rootQuery = criteriaQuery.from(getPersistenceClass());
        CriteriaQuery<T> select = criteriaQuery.select(rootQuery);

        List<Predicate> aPredicateList = new ArrayList<Predicate>();
        Iterator<SingularAttribute<T, ?>> anIterator = theAttributes.keySet().iterator();
        while (anIterator.hasNext()) {
            SingularAttribute<T, ?> aKey = anIterator.next();
            Object aValue = theAttributes.get(aKey);
            Predicate aPredicate = queryBuilder.equal(rootQuery.get(aKey), aValue);
            aPredicateList.add(aPredicate);
        }

        select.where(aPredicateList.toArray(new Predicate[0]));
        TypedQuery<T> typedQuery = entityManager.createQuery(select);

        return typedQuery.getResultList();
    }

    @Override
    public Long getCount() {
        return getCount(null, false);
    }

    @Override
    public Long getCount(Map<SingularAttribute<T, ?>, Object> filterAttributes, boolean enableLikeSearch) {
        CriteriaBuilder queryBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Long> criteriaQuery = queryBuilder.createQuery(Long.class);
        Root<T> rootQuery = criteriaQuery.from(getPersistenceClass());
        CriteriaQuery<Long> select = criteriaQuery.select(queryBuilder.count(rootQuery));

        List<Predicate> predicateList = createFilterList(filterAttributes, enableLikeSearch, queryBuilder,
                rootQuery);
        criteriaQuery.where(predicateList.toArray(new Predicate[0]));

        TypedQuery<Long> typedQuery = entityManager.createQuery(select);
        return typedQuery.getSingleResult();
    }

    @SuppressWarnings("unchecked")
    private List<Predicate> createFilterList(Map<SingularAttribute<T, ?>, Object> filterAttributes,
            boolean enableLikeSearch, CriteriaBuilder queryBuilder, Root<T> rootQuery) {
        List<Predicate> predicateList = new ArrayList<Predicate>();
        if (filterAttributes != null) {
            Iterator<SingularAttribute<T, ?>> iter = filterAttributes.keySet().iterator();
            while (iter.hasNext()) {
                SingularAttribute<T, ?> key = iter.next();
                Object value = filterAttributes.get(key);
                if (enableLikeSearch) {
                    String searchKey = value.toString();
                    if (!value.toString().contains("%")) {
                        searchKey = "%" + value.toString() + "%";
                    }

                    Expression<String> lowerKey = queryBuilder.lower((Expression<String>) rootQuery.get(key));
                    Predicate predicate = queryBuilder.like(lowerKey, searchKey.toLowerCase());
                    predicateList.add(predicate);
                } else {
                    Predicate predicate = queryBuilder.equal(rootQuery.get(key), value);
                    predicateList.add(predicate);
                }
            }
        }
        return predicateList;
    }

    @Override
    public TransactionStatus getTransaction() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setName("CustomTransaction");
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        return txManager.getTransaction(def);
    }

    @Override
    public void commit(TransactionStatus status) {
        txManager.commit(status);
    }

    @Override
    public void rollback(TransactionStatus status) {
        txManager.rollback(status);
    }

    protected EntityManager getEntityManager() {
        return entityManager;
    }

    protected FilteredEntityManager getFilteredEntityManager() {
        if (entityManager instanceof FilteredEntityManager) {
            return (FilteredEntityManager) entityManager;
        } else {
            throw new IllegalStateException("Current entity manager is not filtered.");
        }
    }

    /**
     * Allow subclasses to inject their own entity manager.
     * This is useful when multiple datasources/entity managers will be used.
     * 
     * @param em the entity manager
     */
    protected void setEntityManager(EntityManager em) {
        this.entityManager = em;
    }

    public List<T> findByAssignedEntity(ListAttribute<T, ?> listAttribute, Long entityId) {
        CriteriaBuilder queryBuilder = getEntityManager().getCriteriaBuilder();

        CriteriaQuery<T> criteriaQuery = queryBuilder.createQuery(getPersistenceClass());
        Root<T> rootQuery = criteriaQuery.from(getPersistenceClass());

        CriteriaQuery<T> select = criteriaQuery.select(rootQuery);
        Join<T, ?> memberJoin = rootQuery.join(listAttribute);

        Path<?> nameField = memberJoin.get("id");
        Predicate nameEquals = queryBuilder.equal(nameField, entityId);
        criteriaQuery.where(nameEquals);

        TypedQuery<T> typedQuery = getEntityManager().createQuery(select);

        return typedQuery.getResultList();
    }

    public List<T> findByAssignedEntity(SetAttribute<T, ?> setAttribute, Long entityId) {
        CriteriaBuilder queryBuilder = getEntityManager().getCriteriaBuilder();

        CriteriaQuery<T> criteriaQuery = queryBuilder.createQuery(getPersistenceClass());
        Root<T> rootQuery = criteriaQuery.from(getPersistenceClass());

        CriteriaQuery<T> select = criteriaQuery.select(rootQuery);
        Join<T, ?> memberJoin = rootQuery.join(setAttribute);

        Path<?> nameField = memberJoin.get("id");
        Predicate nameEquals = queryBuilder.equal(nameField, entityId);
        criteriaQuery.where(nameEquals);

        TypedQuery<T> typedQuery = getEntityManager().createQuery(select);

        return typedQuery.getResultList();
    }

}