Tjaart van Wijck wrote: > Guillaume, > > That worked! Thanks a lot for the help. > > Yet, I still don't understand why the HQL string below does not yield > the correct results: > $query = "select obj from BaseObject obj where > obj.className='Contacts.ContactClass'" > > Can someone explain how XWiki traverses documents and objects to > generate the resultset when executing HQL statements?
$xwiki.selectDocuments is a "safe" method, because it allows to select only document names. $xwiki.search is a "privileged" method, because it allows a user to retrieve ANYTHING from the database, even data he might not have access to, like private documents or user emails or passwords (fortunately the passwords are not stored in plaintext in the database, so that is not an issue, but simple passwords could be cracked using brute force dictionary attacks). For this reason $xwiki.search requires programming rights, and is not the recommended method for retrieving information. This is why your query does not work: $xwiki.search("select obj from BaseObject obj...") will return what you told it to select: instances of BaseObject, which is the privileged com.xpn.xwiki.objects.BaseObject class, privileged as in "it should not be exposed to the scripting world". However, since you're already using a privileged method to retrieve them, that is not a problem by itself anymore. But these objects have different methods than the object API which is regularly used in velocity scripts, located in com.xpn.xwiki.api.Object, so $item.get does not work because it is not a method of that object. When you see that a method that is supposed to work doesn't, like was the case with your $item.get, then either the object is null, or has a different type than you expect it to be. What you should do in this case is try to see what's wrong, and you do this by writing: $item $item.class This will print either $item, if it is null, or something for $item followed by the real class name. You then go to that class documentation and see what you should use. So a working script would be: #set($query="select obj from BaseObject obj where obj.className='Contacts.ContactClass'") #set($results=$xwiki.search($query, 10, 1)) #foreach ($item in $results) #set($item = $item.newObjectApi($item, $context.context)) $item.get("firstname") | $item.get("surname") | $item.get("phone1") <br /> #end or: #set($query="select obj from BaseObject obj where obj.className='Contacts.ContactClass'") #set($results=$xwiki.search($query, 10, 1)) #foreach ($item in $results) $item.displayView("firstname", $context.context) | $item.displayView("surname", $context.context) | $item.displayView("phone1", $context.context) <br /> #end Either one of these is NOT recommended, as they require programming rights. The proper way is: #set($query=", BaseObject obj where obj.name = doc.fullName and obj.className='Contacts.ContactClass' and obj.name <> 'Contacts.ContactClassTemplate'") ## Replace with the real name of your template document, if there is one #set($results=$xwiki.searchDocuments($query, 10, 1)) #foreach ($docName in $results) #set($docItem = $xwiki.getDocument($docName)) #foreach($item in $docItem.getObjects("Contacts.ContactClass)) $docItem.display("firstname", $item) | $docItem.display("surname", $item) | $docItem.display("phone1", $item) <br /> #end #end This is different from the other suggested scripts because it does not assume that there is only one object in each document, but it iterates over each object of that type. -- Sergiu Dumitriu http://purl.org/net/sergiu/ _______________________________________________ users mailing list users@xwiki.org http://lists.xwiki.org/mailman/listinfo/users