There were quite a few comments in response to my post about Criteria queries. I finally get around to responding. A number of people suggest a more tree-oriented approach, where we treat all logical operators as binary. For example, anonymous suggests the following:
session.createCriteria( Project.class, or( eq("name", "Hibernate"), like("description", "%ORM%") ) );
Now, certainly logical operations are binary. But they are also /associative/, and this seems to be denied by the tree approach. We would never, ever write:
( (x=2 and x=1) and y=3 ) and z=4
We always write:
x=2 and x=1 and y=3 and z=4
This is particularly relevant in the case of Criteria queries since the common case is that we compose together many conditions using conjunction. (There were objections to my use of
disjunction, but I don't know of any other word for a string of expressions composed with
Actually, the current API /does/ already allow this alternative. We have Expression.or() and Expression.and(). But to me they seem to be much messier than add().
In my opinion a clean object querying system is the first and foremost basis for any standard on object persistence. Enhancers/Reflection/BCEL/code calls to make objects persistent all this can be very quickly exchanged, if you want to switch the underlying system. Queries can not be exchanged!
And I couldn't possibly agree more! This is absolutely right. He goes on to say:
Could you maybe bring this thought into JDO 2.0 ? Please ? Besides, I am positive that a de-facto standard for object querying will have a much greater impact on the industry than JDO. Java is not the only programming language on this planet.
In fact, I've mentioned the idea of adopting a better query approach to a couple of the guys on the expert group, but didn't get much of a positive response. Besides, I'm not at all convinced that it is even possible to design a nice query language or API in a committee environment. These kind of things need a strong unified vision. Comittees are okay at standardizing mature solutions to well-understood problems, but it is my view that object-oriented querying is a far from well understood problem. Especially, it does not seem to be commonly appreciated that an ORM-oriented query language would look quite different to an object database query language!
James Strachan is pimpin' Groovy , his new JVM-compatible language (I'm not sure if its quite correct to call it a scripting language) that looks quite like Python but features one of the best things about SmallTalk: closures. (Digression: it seems to be widely believed that the JDK Collections API is one of Java's good points. But if you've ever used collections in SmallTalk, you'll know just how impoverished Java actually is when it comes to working with collections. Iterators are far, far uglier than the more functional approach available in languages with closures. If there is /anything/ that I would ask to be fixed in Java, it wouldn't be the lack of generics, the lack of enums, etc, etc - it would be the lack of closures.) Anyway, I'm interested in what James has to say, but I'm skeptical toward the notion that an object-oriented expression language is the right starting point for an ORM query language. Firstly, relational databases implement very different null value semantics to object oriented languages. In fact, SQL's ternary logic is /quite/ different to the binary logic implemented by programming languages. Secondly, equality is a much more slippery concept in the object oriented world than in the database world. For these reasons, and others, we have chosen to base HQL on SQL, not on Java-like syntax. It is my view that this was one of the best decisions we've made.
Razvan describes what (s)he calls an
an associative query model (much like the query in JavaSpaces). If I'm not mistaken, this is what we usually call
query by example. I'll get round to discussing Hibernate's new Example query API in a future post...