Query by Example and refactoring

I am working on an project to expand an existing application with a large set of new features. Some of these features require domain model changes. As these changes happen we are also refactoring the existing model to better match the new business requirements.

In this application we use Hibernate for the object persistence. As we refactor we sometimes rename javabean properties in our domain model using Eclipse automated renaming feature. This works fine for Java code but breaks the HQL queries which we have to modify manually. We use XDoclet for the mapping metadata so we do not have to manually edit the XML mapping files since they are generated.

One good way to get rid of the pain to have to modify your HQL when you change your domain model is not to use HQL but criteria queries with query by example(QBE).

In query by example you create an example object, an object that looks like the objects you want to fetch with the query. This object is then used by Hibernate to generate the SQL query for you. Let’s illustrate this with a small example.

User exampleUser = new User();
exampleUser.setFirstName(“Spiros”);
Example e = Example.create(exampleUser);
Criteria c = session.createCriteria(User.class);
c.add(e);
c.list();

The above code will retrieve all the User objects with firstName equals “Spiros”.

Please note that example queries can also work for associations and not only for properties.

From the above example it is clear that we have not used any form of query language or special object to express our query. We have used just an instance of the class whose objects we want to retrieve. When we rename a property using a modern IDE the above query will continue to work.

Example queries are not a silver bullet. HQL and Criteria Queries (with criteria expressions not only examples) provide more powerful ways to query your relational database but example queries for simple queries are just fine and allow easier domain object changes.

For more info on Hibernate QBE see here.