Question

I'm trying to create a page for CQ based on the jcr API. I'd like to query pages containing a specific string in a property.

The query itself (JCR-SQL2) is the following (I tested it on the CQ Web interface and it delivers results):

SELECT
    *
FROM 
    [nt:base] AS s
WHERE
    ISDESCENDANTNODE([/content])
AND
    s.[sling:resourceType] = 'some/path/to/destination'

This was my try in the JSP page:

    String stmt = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/content]) AND s.[cq:template] = 'some/path/to/destination'";
    Query query = currentNode.getSession().getWorkspace().getQueryManager().createQuery(stmt, Query.JCR_SQL2);
    QueryResult results = query.execute();
    if (results.getNodes() != null && results.getNodes().hasNext()) {
        NodeIterator it = results.getNodes();

        while (it.hasNext()) {
            Node node = it.nextNode();
            String npath = node.getPath();
            Page contentPage = pageManager.getContainingPage(resourceResolver.getResource(npath));
            String title = contentPage.getTitle();
            String path = contentPage.getPath() + ".html";
            %>
            <div class="searchresult"><a href="<%= path %>"><%= title %></a></div>
            <%
        }
    }

The error thrown is the following:

Caused by: javax.jcr.RepositoryException: This query result has already been iterated through
Was it helpful?

Solution

Is it not because you create an iterator two times: First

if (results.getNodes() != null && results.getNodes().hasNext()) {

and then

NodeIterator it = results.getNodes();

I would try to create it only once like this:

   QueryResult results = query.execute();
   NodeIterator it = results.getNodes();
   if (it.hasNext()) {
   ...
   }

Looking at source of SimpleQueryResult, it's doing something strange , the instance variable rowIterator is set to null, so the next time getRows is called you'll go the else part of the condition and you'll have the error you mentionned:

  public synchronized RowIterator getRows() throws RepositoryException {
        if (rowIterator != null) {
            RowIterator iterator = rowIterator;
            rowIterator = null;
            return iterator;
        } else {
            throw new RepositoryException(
                    "This query result has already been iterated through");
        }
}

https://svn.apache.org/repos/asf/jackrabbit/branches/2.2/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/SimpleQueryResult.java

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top