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

com.devonfw.module.jpa.dataaccess.base.AbstractGenericDao Maven / Gradle / Ivy

package com.devonfw.module.jpa.dataaccess.base;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.devonfw.module.basic.common.api.entity.PersistenceEntity;
import com.devonfw.module.basic.common.api.reference.Ref;
import com.devonfw.module.jpa.dataaccess.api.GenericDao;
import com.devonfw.module.jpa.dataaccess.api.QueryHelper;

/**
 * This is the abstract base-implementation of the {@link GenericDao} interface.
 *
 * @param  is the generic type if the {@link PersistenceEntity#getId() primary key}.
 * @param  is the generic type of the managed {@link PersistenceEntity}.
 */
public abstract class AbstractGenericDao> extends QueryHelper
    implements GenericDao {

  /** Logger instance. */
  private static final Logger LOG = LoggerFactory.getLogger(AbstractGenericDao.class);

  private EntityManager entityManager;

  /**
   * The constructor.
   */
  public AbstractGenericDao() {

    super();
  }

  /**
   * @return the {@link Class} reflecting the managed entity.
   */
  protected abstract Class getEntityClass();

  /**
   * @return the {@link EntityManager} instance.
   */
  protected EntityManager getEntityManager() {

    return this.entityManager;
  }

  /**
   * @param entityManager the {@link EntityManager} to inject.
   */
  @PersistenceContext
  public void setEntityManager(EntityManager entityManager) {

    this.entityManager = entityManager;
  }

  /**
   * @return the name of the managed entity.
   */
  protected String getEntityName() {

    return getEntityClass().getSimpleName();
  }

  @Override
  public E save(E entity) {

    if (isNew(entity)) {
      getEntityManager().persist(entity);
      LOG.debug("Saved new {} with id {}.", getEntityName(), entity.getId());
      return entity;
    } else {
      if (getEntityManager().find(entity.getClass(), entity.getId()) != null) {
        E update = getEntityManager().merge(entity);
        LOG.debug("Updated {} with id {}.", getEntityName(), entity.getId());
        return update;
      } else {
        throw new EntityNotFoundException("Entity not found");
      }
    }
  }

  /**
   * Determines if the given {@link PersistenceEntity} is new.
   *
   * @param entity is the {@link PersistenceEntity} to check.
   * @return {@code true} if new, {@code false} otherwise (e.g. managed or detached).
   */
  protected boolean isNew(E entity) {

    return entity.getId() == null;
  }

  @Override
  public void save(Iterable entities) {

    for (E entity : entities) {
      save(entity);
    }
  }

  @Override
  public void forceIncrementModificationCounter(E entity) {

    getEntityManager().lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
  }

  @Override
  public E findOne(ID id) {

    E entity = getEntityManager().find(getEntityClass(), id);
    return entity;
  }

  @Override
  public E find(ID id) {

    E entity = findOne(id);
    if (entity == null) {
      throw new IllegalStateException(
          "Entity " + getEntityClass().getSimpleName() + " with ID '" + id + "' was not found!");
    }
    return entity;
  }

  @Override
  public E get(Ref reference) {

    if (reference == null) {
      return null;
    }
    return getEntityManager().getReference(getEntityClass(), reference.getId());
  }

  @Override
  public boolean exists(ID id) {

    // pointless...
    return findOne(id) != null;
  }

  /**
   * @return an {@link Iterable} to find ALL {@link #getEntityClass() managed entities} from the persistent store. Not
   *         exposed to API by default as this might not make sense for all kind of entities.
   */
  public List findAll() {

    CriteriaQuery query = getEntityManager().getCriteriaBuilder().createQuery(getEntityClass());
    Root root = query.from(getEntityClass());
    query.select(root);
    TypedQuery typedQuery = getEntityManager().createQuery(query);
    List resultList = typedQuery.getResultList();
    LOG.debug("Query for all {} objects returned {} hit(s).", getEntityName(), resultList.size());
    return resultList;
  }

  @Override
  public List findAll(Iterable ids) {

    CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
    CriteriaQuery query = builder.createQuery(getEntityClass());
    Root root = query.from(getEntityClass());
    query.select(root);
    query.where(root.get("id").in(toCollection(ids)));
    TypedQuery typedQuery = getEntityManager().createQuery(query);
    List resultList = typedQuery.getResultList();
    LOG.debug("Query for selection of {} objects returned {} hit(s).", getEntityName(), resultList.size());
    return resultList;
  }

  /**
   * @param ids sequence of id
   * @return a collection of these ids to use {@link Predicate#in(Collection)} for instance
   */
  protected Collection toCollection(Iterable ids) {

    if (ids instanceof Collection) {
      return (Collection) ids;
    }

    final Collection idsList = new ArrayList<>();
    for (final ID id : ids) {
      idsList.add(id);
    }
    return idsList;
  }

  @Override
  public void delete(ID id) {

    E entity = getEntityManager().getReference(getEntityClass(), id);
    getEntityManager().remove(entity);
    LOG.debug("Deleted {} with ID {}.", getEntityName(), id);
  }

  @Override
  public void delete(E entity) {

    // entity might be detached and could cause trouble in entityManager on remove
    if (getEntityManager().contains(entity)) {
      getEntityManager().remove(entity);
      LOG.debug("Deleted {} with ID {}.", getEntityName(), entity.getId());
    } else {
      delete(entity.getId());
    }

  }

  @Override
  public void delete(Iterable entities) {

    for (E entity : entities) {
      delete(entity);
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy