Oliver Gierke Archive About Tags

Enabling Hibernate criteria query statistics with AspectJ

15 September 2010

In the #java.de IRC channel someone pointed me to this request for enhancement in Hibernate recently. The bottom line here is that Hibernate’s statistics feature that can be used to capture persistence metrics (information about query executions and execution times and so on) does not include queries triggered through using the criteria API.

This is quite a a reasonable request for enhancement in my opinion and it’s quite surprising that the ticket has been open for over 2 years now, especially as the solution seems to be simply adding a method to CriteriaLoader class, as Chuck May points out. So supposed you want to use this feature now. The only option seems to be patching Hibernate (sort of doable), building it (a huge magnitude more complex – no offense, building Spring is not trivial either) and the use and maintain that patched version over further releases. Isn’t there another way to get that feature into Hibernate? Of course there is… AspectJ. As the fix seems to be simply adding a method to an existing class we can leverage AspectJ inter-type declarations to add this special method from the outside. Here’s the aspect code:

public privileged aspect CriteriaStatisticsAspect {
  public String CriteriaLoader.getQueryIdentifier() {
    return "[CRITERIA] " + getSQLString();
  }
}

It’s pretty easy to understand I think as the method declaration only slightly differs from a normal Java one (no pun intended). You actually only have to explicitly mention the type you want to add the method to. To weave this aspect into Hibernate you simply add the Maven AspectJ plugin to your pom.xml and tell it to consider the Hibernate JARs too by adding a weaveDependencies block to the configuration section of the plugin.

To ease the burden of getting started with this approach I have uploaded the sample code to Github, also containing a test case to demonstrate this actually works. Upgrading to another Hibernate versions should work seamlessly as the aspect gets woven into the never version then. As soon as the feature gets actually implemented (let’s hope it won’t take another two years ;) simply throw away the aspect.

blog comments powered by Disqus
Fork me on GitHub