CQ QueryBuilder API.. why? - aem

Why is there need of QueryBuilder API in AEM / CQ when we can use JCR Query API? What does it provide that the former doesn't? Or is it just a non-SQL alternative to JCR API?
We are currently building a module which fetches info from JCR nodes and wanted to know the best way to go about it.
Thank you.

Query Builder is built on top of JCR Query API. What does query builder provide that JCR API doesn't ? IMHO it would be Usability. You deal with a map of predicates instead of queries. The Out of the box predicates work in most situations. The limit and offset features work like a charm for pagination situations. Grouping let's you write complex queries in a very readable manner. One more nice feature is the faceted search , your search results can be split by tags. Query Builder returns Resources and not nodes so you don't have to handle to deal with those checked repository exceptions that come along with JCR api ( https://cqdump.wordpress.com/2012/11/06/cq5-coding-patterns-sling-vs-jcr-part-1/ ).
Since it is exposed as a REST servlet it is often used in building interfaces like custom dashboards and the familiarity helps.
It's an abstraction so you are shielded from changes at lower level. Some of the queries that used to work in JackRabbit 2 don't work in the newer Oak (Aem 6) but all the query builder one's still work.
Faceted search example :
http://localhost:4502/libs/cq/search/content/querydebug.html?charset=UTF-8&facets=on&isURL=on&query=http%3A%2F%2Flocalhost%3A4502%2Fbin%2Fquerybuilder.json%3Ftype%3Dcq%3APage%26tagid%3Dmarketing%3Ainterest%2Fproduct%26tagid.property%3Djcr%3Acontent%2Fcq%3Atags
Query Builder Details : http://www.slideshare.net/alexkli/cq5-querybuilder-adapttoberlin-2011

Related

Microsoft Dynamics predefined query

We are writing a web service that needs to query a somewhat complex dataset from MS Dynamics. By "somewhat complex", I mean it needs to query multiple levels of the entity hierarchy. The Dynamics oData implementation limits the depth of oData queries to two (i.e. you can query a parent and a child - but not that child's child).
One way of moving forward would be to walk the entity hierarchy by making thousands of oData calls, but this is not at all appealing (kind of defeats the entire purpose of server side databases).
Another wrinkle is that we need to interact with many different Dynamics systems, none of which will allow us to load a custom .NET plugin. It probably doesn't matter, but we are writing our client-side code in Java, and really do need to use regular REST type calls.
I was thinking that if there were a way to predefine a data report in Dynamics that hits the complex query, that we could then maybe query that report via the REST interface. So far, I haven't found a way to do this, and I thought I'd toss this out to the community to see if anyone has any suggestions.
you can create a Query object in NAV and publish the Query Object as a Webservice
If the Query Object is not available in NAV (NAV version < 2013) you can create codeunit, generate the dataset in there and publish the codeunit as a webservice.
The third option is if the NAV is running on SQL server you can create a View/TempTable/Stored Procedure in there to create the dataset; or use SQL Analysis Services
Cheers!
We wound up dropping the REST API entirely and using SOAP instead. From there, we can do FetchXML and get what we need.

Combining Spring Data query builder with Spring Data JPA Specifications?

Spring Data allows you to declare methods like findByLastname() in your repository interface and it generates the queries from the method name automatically for you.
Is it possible to somehow have these automatically-generated queries also accept a Specification, so that additional restrictions can be made on the data before it's returned?
That way, I could for example call findByLastname("Ted", isGovernmentWorker()), which would find all users that have the last name Ted AND who satisfy the isGovernmentWorker() specification.
I need this because I'd like the automated query creation provided by Spring Data and because I still need to be able to apply arbitrary specifications at runtime.
There is no such feature. Specifications can only be applied on JpaSpecificationExecutor operations.
Update
The data access operations are generated by a proxy. Thus if we want to group the operations (as in findByName + Criteria) in a single SELECT call, the proxy must understand and support this kind of usage; which it does not.
The intended usage, when employing Specification API would look like this for your case:
findAll(Specifications.where(hasLastName("Ted")).and(isGovernmentWorker())
Spring data allows you to implement custom repository and use Specifications or QueryDSL.
Please see this article.
So at the end you will have one YourCustomerRepository and appropriate YourRepositoryImpl implementation, where you will put your findByLastname("Ted", isGovernmentWorker()) method.
And then YourRepository should extend YourCustomerRepository interface.

Generating DAO with Hibernate Tools on Eclipse

How can I use the tools to generate DAOs?
In fact, instead of passing through the hbm files, I need to configure hibernate tools to generate the DAO and the annotations.
See Hibernate Tools - DAO generation and How generate DAO with Hibernate Tools in Eclipse?
First let me assume DAO as POJO/Entity beans. Basically you can accomplish your task either through forward or reverse engineering. In case of forward engineering, probably you can look into AndroMDA tool. In case If u wish to accomplish it through reverse engineering Click here ..
Hope this will be helpful.
Welcome. You got to write all your data access logic by your hand (if I’m not wrong). Hiberante let you interact with database in three ways.
Native SQL which is nothing but DDL/plain SQL query. This can be used very rarely in hibernate projects even though this is faster than below mentioned options. Reason is simple “One of the key advantage of hibernate or any other popular ORM framework over JDBC Is you can get rid of database specific queries from your application code!”
HQL stands for hibernate query language which is proprietary query language of hibernate. This looks similar to native SQL queries but the key difference is object/class name will be used instead of table name and public variable names will be used instead of column names. This is more Object oriented approach. Some interesting things will be happening in background and check if you are keen!
Criteria API is a more object oriented and elegant alternative to Hibernate Query Language (HQL). It’s always a good solution to an application which has many optional search criteria.
You can find lots of examples on internet. Please post your specific requirements for further clarification on your problem.
Cheers!

Mongo C# Driver OData issue "Where with predicate after a project is not supported"

Request: /api/person?$filter Name eq 'John' with server backed up method that
return repo.GetAll().Select(o => Mapper.Map<>PersonDTO>(o));
Only the $filter requests error out with "Where with predicate after a project is not supported" but $top / $skip / $orderby work fine. My guess is, Mongo C# has a bug while generating the query & projects before applying the filter. Instead it should apply filter first and then project. I am using OData 5.2.0-rc1 and Mongo C# driver is 1.7.
Any inputs are much appreciated. Thanks...
That is a limitation in the current implementation of Linq. We are working to correct that with this ticket: https://jira.mongodb.org/browse/CSHARP-601.
However, I'd encourage you to figure out what you are actually attempting to do. Projecting prior to a filter could mean you are filtering on computed expressions, such as adding 2 columns together. MongoDB queries do not support this type of behavior, which is why this is currently disallowed by our linq provider. Aggregation framework allows this to a point, but there are a different set of limitations imposed by the Aggregation framework.
In your particular case, what you are wanting us to do is impossible. You are asking us to know how to create a MongoDB query based on an AutoMapper generated object. This simply impossible unless we (at runtime) read the AutoMapper mapping and apply it to our internal class models.

How to expose read model from shared module

I am working on developing a set of assemblies that encapsulate parts of our domain that will be shared by many applications. Using the example of an order management system, one such assembly will contain all of the core operations an application can perform to/with an order. We are applying a simple version of CQS/CQRS so that all operations that change the state of the "system" are represented as public commands, such as CancelOrderCommand, ShipOrderCommand and CreateORderCommand. The command handlers are internal to the assembly.
The question I am struggling to answer is how to best expose the read model to consuming code?
The read model will be used by consuming code to perform queries. I don't know how all of the ways the read model will be used so the interface needs to be flexible to allow any query.
What complicates it for me is that I not only need to expose my aggregate root but there are also several "lookup" lists of related data that client applications may use. For example, each order has an associated OrderType which is data-driven (i.e., not an enum) and contains several properties that will drive some of our business rules that control what operations can/cannot be performed, etc. It is easy inside my module to manage this relationship; however, a client application that allows order creation will most likely need to display the list of possible OrderTypes to the user. As a result, I need to not only expose the list of Order aggregates but the supporting list of OrderTypes (and other lookup lists) from my read model.
How is this typically done?
I'm not sure what else to explain that will help trigger a solution, so please ask away...
I have never seen a CQRS based implementation expose a full dataset for ad-hoc querying so this is an interesting situation! In a typical CQRS scenario you would expose very specific queries because you may want to raise events when they are called (for caching for example - see this post for more details on that).
However since this is your design, let's not worry about "typical" or "correct" CQRS, I guess you just need a solution! One of the best new mechanisms for exposing data for flexible querying I have seen is the Open Data Protocol (OData). It will allow consumers to implement their own filtering, sorting and paging over a data source you expose.
Most implementations of this seem to deal with relational data. If you are dealing with a relational data source then OData might be a nice way to go. I suspect by your comment of "expose my aggregate root" that you might be using a document database? If so, there is one example I have seen of OData services on top of MongoDB: http://bloggingabout.net/blogs/vagif/archive/2012/10/11/mongodb-odata-provider-now-supports-arrays-and-nested-collections.aspx.
I hope that helps, OData is definitely worth looking into. It seems to be growing really quickly and is getting good support on both server and client technology platforms.