@Override
 public Page<M> findAll(final Pageable pageable) {
   return new PageImpl<M>(
       repositoryHelper.<M>findAll(findAllQL, pageable),
       pageable,
       repositoryHelper.count(countAllQL));
 }
  @Transactional
  @Override
  public void deleteInBatch(final Iterable<M> entities) {
    if (entities == null) {
      return;
    }
    Iterator<M> iter = entities.iterator();
    if (!iter.hasNext()) {
      return;
    }

    Set models = Sets.newHashSet(iter);

    boolean logicDeleteableEntity = LogicDeleteable.class.isAssignableFrom(this.entityClass);

    if (logicDeleteableEntity) {
      String ql = String.format(LOGIC_DELETE_ALL_QUERY_STRING, entityName);
      repositoryHelper.batchUpdate(ql, models);
    } else {
      String ql = String.format(DELETE_ALL_QUERY_STRING, entityName);
      repositoryHelper.batchUpdate(ql, models);
    }
  }
  /**
   * Creates a new count query for the given {@link
   * org.springframework.data.jpa.domain.Specification}.
   *
   * @param spec can be {@literal null}.
   * @return
   */
  protected TypedQuery<Long> getCountQuery(Specification<M> spec) {

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Long> query = builder.createQuery(Long.class);

    Root<M> root = applySpecificationToCriteria(spec, query);

    if (query.isDistinct()) {
      query.select(builder.countDistinct(root));
    } else {
      query.select(builder.count(root));
    }

    TypedQuery<Long> q = em.createQuery(query);
    repositoryHelper.applyEnableQueryCache(q);
    return q;
  }
  /**
   * Creates a {@link javax.persistence.TypedQuery} for the given {@link
   * org.springframework.data.jpa.domain.Specification} and {@link
   * org.springframework.data.domain.Sort}.
   *
   * @param spec can be {@literal null}.
   * @param sort can be {@literal null}.
   * @return
   */
  protected TypedQuery<M> getQuery(Specification<M> spec, Sort sort) {

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<M> query = builder.createQuery(entityClass);

    Root<M> root = applySpecificationToCriteria(spec, query);
    query.select(root);

    applyJoins(root);

    if (sort != null) {
      query.orderBy(toOrders(sort, root, builder));
    }

    TypedQuery<M> q = em.createQuery(query);

    repositoryHelper.applyEnableQueryCache(q);

    return applyLockMode(q);
  }
 @Override
 public long count(final Searchable searchable) {
   return repositoryHelper.count(countAllQL, searchable, searchCallback);
 }
 @Override
 public Page<M> findAll(final Searchable searchable) {
   List<M> list = repositoryHelper.findAll(findAllQL, searchable, searchCallback);
   long total = searchable.hasPageable() ? count(searchable) : list.size();
   return new PageImpl<M>(list, searchable.getPage(), total);
 }
 @Override
 public long count() {
   return repositoryHelper.count(countAllQL);
 }
 @Override
 public List<M> findAll(final Sort sort) {
   return repositoryHelper.findAll(findAllQL, sort);
 }
 @Override
 public List<M> findAll() {
   return repositoryHelper.findAll(findAllQL);
 }