Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

Adobe Summit 2023 [19th to 23rd March, Las Vegas and Virtual] | Complete AEM Session & Lab list

JQOM - \'Duplicate\' rows returned


Not applicable



Hi guys, I am encountering some trouble with JCR-JQOM. The image above shows the structure I am working on.

  • ​I have a set of pages in /content/mySite/myFolder
  • Each one of these pages has a couple of sub-pages
  • In the jcr:content of these sub-pages there is a property, let's say it's called myProperty, which is a String

Let's assume that the value of myProperty is "someValue" for the sub-pages of /content/mySite/myFolder/firstPage, while the sub-pages of /content/mySite/myFolder/secondPage have some different values for this property.

If you want to find all the pages in /content/mySite/myFolder that have a sub-page with the property "myProperty" set to "someValue", you can do something like

SELECT * FROM [cq:Page] AS page INNER JOIN [cq:Page] AS subPage ON ISCHILDNODE(subPage, page) INNER JOIN [nt:unstructured] AS subPageJcrContent ON ISCHILDNODE(subPageJcrContent, subPage) WHERE ISCHILDNODE(page, [/content/mySite/myFolder]) AND CONTAINS(subPageJcrContent.myProperty, 'someValue')

Running this query via CRX DE, you get the one row you are expecting to be returned, which is the node /content/mySite/myFolder/firstPage.

Everything sounds just fine till now, but...
The equivalent JQOM for this should be the following:

QueryObjectModelFactory qf = session.getWorkspace().getQueryManager().getQOMFactory(); Selector pageSelector = qf.selector("cq:Page", "page"); Selector subPageSelector = qf.selector("cq:Page", "subPage"); Selector subPageJcrContentSelector = qf.selector("nt:unstructured", "subPageJcrContent"); Join join = qf.join(pageSelector, subPageSelector, QueryObjectModelFactory.JCR_JOIN_TYPE_INNER, qf.childNodeJoinCondition(subPageSelector.getSelectorName(), pageSelector.getSelectorName())); join = qf.join(join, subPageJcrContentSelector, QueryObjectModelFactory.JCR_JOIN_TYPE_INNER, qf.childNodeJoinCondition(subPageJcrContentSelector.getSelectorName(), subPageSelector.getSelectorName())); Constraint constraint = qf.childNode(pageSelector.getSelectorName(), "/content/istituzionale20/myFolder"); constraint = qf.and(constraint, qf.fullTextSearch(subPageJcrContentSelector.getSelectorName(), "ingredients", qf.literal(vf.createValue("lol")))); QueryObjectModel query = qf.createQuery(join, constraint, null, null);

The query runs fine but the problem is: if I print the rows (this sample code is running within a JSP page) with the following code:

<% QueryResult queryResult = query.execute(); RowIterator rowIterator = queryResult.getRows();%> <% while(rowIterator.hasNext()) { Node currentNode1 = rowIterator.nextRow().getNode(ricettaPageSelector.getSelectorName()); %> This is the path: <%=currentNode1.getPath()%><br> <% } %>

the output is

This is the path: /content/mySite/myFolder/firstPage This is the path: /content/mySite/myFolder/firstPage


That is, the same node is returned twice. If the page /content/mySite/myFolder/firstPage would have had 3 pages with that property set at the desired value, the output would have been

This is the path: /content/mySite/myFolder/firstPage This is the path: /content/mySite/myFolder/firstPage This is the path: /content/mySite/myFolder/firstPage


I don't see why this is happening, and I am also curious about this difference between the result I get in CRX DE and the output of my JSP.

Did any of you know how to avoid this behaviour?



1 Accepted Solution


Correct answer by
Level 10

Any reason why you using this API as opposed to the AEM QueryBuilder API - i would recommend the AEM QueryBuilder API? 

4 Replies


Not applicable

Hi Sam, thanks for your reply.


Unfortunately, it seems to be a different issue. In his post, Dmitri says he got 1 node when querying via the javax.jcr.query.QueryManager, and 3 when using QueryObjectModelFactory, while I get "duplicated" rows in both cases.


Correct answer by
Level 10

Any reason why you using this API as opposed to the AEM QueryBuilder API - i would recommend the AEM QueryBuilder API? 


Not applicable

I just found some tutorial using the QueryObjectModelFactory and I stuck to it since it was suggested as the "right way" to query the CRX (rather than just passing a query as a String). I know that QueryBuilder works in a similar way, but I read that it translates your parameters into an XPath query; isn't XPath deprecated?