@Override
    public SpanResult selectSpan(TransactionId transactionId, Predicate<SpanBo> filter, ColumnGetCount columnGetCount) {
        Objects.requireNonNull(transactionId, "transactionId");
        Objects.requireNonNull(filter, "filter");
        Objects.requireNonNull(columnGetCount, "columnGetCount");

        final FetchResult<List<SpanBo>> fetchResult = traceDao.selectSpan(transactionId, columnGetCount);
        final List<SpanBo> spans = fetchResult.data();
        logger.debug("selectSpan spans:{}", spans.size());

        populateAgentName(spans);
        if (CollectionUtils.isEmpty(spans)) {
            return new SpanResult(TraceState.State.ERROR, new CallTreeIterator(null));
        }

        final boolean isReachedLimit = columnGetCount.isReachedLimit(fetchResult.fetchCount());

        final SpanResult result = order(spans, filter, isReachedLimit);
        final CallTreeIterator callTreeIterator = result.callTree();
        final List<Align> values = callTreeIterator.values();

        transitionDynamicApiId(values);
        transitionSqlId(values);
        transitionSqlUid(values);
        transitionMongoJson(values);
        transitionCachedString(values);
        transitionException(values);

        // TODO need to at least show the row data when root span is not found.
        return result;
    }
@author emeroad
@author jaehong.kim
@author minwoo.jung
web/src/main/java/com/navercorp/pinpoint/web/service/SpanServiceImpl.java