Relational query languages like HQL (and SQL, on which it's based) are extremely flexible and powerful, but they take a long time to truly master. Many application developers get by with a rudimentary understanding, cribbing similar examples from past projects, and calling in database experts when they need to come up with something truly new, or to understand a particularly cryptic query expression.
It can also be awkward to mix a query language's syntax with Java code. The section 'Better Ways to Build Queries' in Chapter 3 showed how to at least keep the queries in a separate file so they can be seen and edited in one piece, free of Java string escape sequences and concatenation syntax. Even with that technique, though, the HQL isn't parsed until the mapping document is loaded, which means that any syntax errors it might harbor won't be caught until the application is running.
Hibernate offers an unusual solution to these problems in the form of criteria queries. They provide a way to create and connect simple Java objects that act as filters for picking your desired results. You can build up nested, structured expressions. The mechanism also allows you to supply example objects to show what you're looking for, with control over which details matter and which properties to ignore.
As you'll see, this can be quite convenient . To be fair, it has its own disadvantages. Expanding long query expressions into a Java API makes them take more room, and they'll be less familiar to experienced database developers than a SQL-like query. There are also some things you simply can't express using the current criteria API, such as projection (retrieving a subset of the properties of a class, e.g., ' select title, id from com.oreilly.hh.Track ' rather than ' select * from com.oreilly. hh.Track ') and aggregation (summarizing results, e.g., getting the sum, average, or count of a property). The next chapter shows how to accomplish such tasks using Hibernate's object-oriented query language.