/**
   * 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);
  }