@Override
  public Object uniqueResult() throws HibernateException {

    // build a shard operation and apply it across all shards
    final ShardOperation<Object> shardOp =
        new ShardOperation<Object>() {

          @Override
          public Object execute(Shard shard) {
            shard.establishCriteria(ShardedCriteriaImpl.this);
            return shard.uniqueResult(criteriaId);
          }

          @Override
          public String getOperationName() {
            return "uniqueResult()";
          }
        };

    /**
     * We don't support shard selection for criteria queries. If you want custom shards, create a
     * ShardedSession with only the shards you want. We're going to return the first non-null result
     * we get from a shard.
     */
    return shardAccessStrategy.apply(
        shards, shardOp, new FirstNonNullResultExitStrategy<Object>(), criteriaCollector);
  }
  @Override
  public List list() throws HibernateException {

    // build a shard operation and apply it across all shards
    final ShardOperation<List<Object>> shardOp =
        new ShardOperation<List<Object>>() {

          @Override
          public List<Object> execute(final Shard shard) {
            shard.establishCriteria(ShardedCriteriaImpl.this);
            return shard.list(criteriaId);
          }

          @Override
          public String getOperationName() {
            return "list()";
          }
        };

    /**
     * We don't support shard selection for criteria queries. If you want custom shards, create a
     * ShardedSession with only the shards you want. We're going to concatenate all our results and
     * then use our criteria collector to do post processing.
     */
    return shardAccessStrategy.apply(
        shards, shardOp, new ConcatenateListsExitStrategy(), criteriaCollector);
  }