How can I allow creation of queries spanning multiple entities and complex entity hierarchies?

You can add attributes which come from a 2nd level imbricated entity attribute, by specifying the name of the attribute with a dot. E.g.: if you have entity mypackage.MyClass which has an attribute of type somepackage.MyOtherClass, named myInner and somepackage.MyOtherClass has an attribute of type String named description, then you can define, within the jpaEntity tag representing mypackage.MyClass, an attribute having attribute name myInner.description (and this can have any display name you want, so the user is not even aware of how your data structure is). If the mapped relationship between the two entities is a one-to-one or one-to-many, this will trigger the creation of an inner join at query compile time, in the back-end.

If you want to create really complex queries, which require custom joins between tables and/or many prefiltering options, then a solution is to create intermediate database views and JPA entities mapped to these views, which will allow you to simplify the problem. Generating more in-dept queries directly in JPQL is not supported in the current version of Infiniquery.

How do I secure my search from prohibite access?

Your application is responsible for handling the login process and the role(s) assigned to the currently logged user. To make Infiniquery aware of the role(s) of the current user, on the backend side, create a custom implementation of SecurityService. Add into it's getCurrentUserRoles() method your custom code which returns the roles of the currently logged user. In most applications, a user can only be logged with a single role at any given time. However, in order to avoid limiting applications with more flexible requirements, this method returns a Set<String>, which may contain zero or more role names. In some cases, you may want to allow an user to access all resources that all of his owned roles grant together, not only the role that he is currently logged as. getCurrentUserRoles() is called by Infiniquery every time before serving any resource to the frontend (no caching, so the value is always up to date). Onceyou have your own implementation of SecurityService, next step is to register it with the dynamic query service: Eg: myDynamicQueryService.setSecurityService(mySecurityService).Next step is to make sure you define the roles allowed to access each resource, in infiniquery-config.xml. You can mention the roles attribute for each jpaEntity tag and you can also mention the roles attribute for each individual entityAttribute of a jpa Entity.

Security checks are done on any kind of request that touches resources having roles specified. Any user can only see in the UI the entities and attributes that (at least) one of his roles is allowed access to and can execute querries only containing these resources. If a query is received containing references to resources the current user is not allowed to access, a SecurityException is thrown from the core of Infiniquery. Default behavior: if roles attribute is missing from a resource definition (jpaEntity or entityAttribute), it means security is off for that particular resource, so everybody is allowed to access it. If some roles are specified for a specific resource and Key sensitivity: role names are not key sensitive.

For security reasons and protection against SQL injection or any other kind of injection from UI, Infiniquery doesn't communicate directly with the database, but is designed to be connected on top of a JPA layer. Also, Infiniquery does not transfere any sensitive information to the UI (such asJPA entity class or variable names), but only the alias (aka display name) that is defined for them in infiniquery-config.xml. However, if you need to do this for administration reasons (e.g. display the JPA dimension of the query into an admin screen, like the demo application does), you can create this functionality in your own controller.

How do I correct my query, once I've done a mistake?

Right-click on a word in the query and you will get displayed a context menu, which is specific to that word. Options like "remove condition", "choose another entity" etc. are displayed in the context menu. Please note that contextual menu is not currently implemented for all type of words, but only for some of them.

Why a single XML file? Isn't it unsuitable for large applications?

In a classic-design application, you would have multiple search screens (a different one for every type of entity that can be searched for). With infiniquery, not only that you don't need multiple search screens, but it is stronlgy recommended that you have everything in one. A single infiniquery screen starts execution by prompting to choose what entity you want to search for. This means that an infiniquery screen successfully replaces all search screens in an application. For an application that has up to 20 searchable entities, there is no complexity issue regarding both screen usability and XML editing. If an application has 30 or more persistent entities, in a code base that executes monolitically, in a single JVM instance, that is most probably a design smell. However, even so, future infiniquery versions may consider to allow a more flexible organization of the configuration XML structure (including child XML files and the possibility to have multiple infiniquery screens in the same web application).