Hibernate How To

 

This page looks at the Hibernate template that comes with Zapcat. It demonstrates how to enable statistics gathering in Hibernate and examines the items that are of interest to monitor over longer periods of time.


For those of you who do not know Hibernate: it is an object-relational mapper, or O/R-mapper for short. It sits between the Java application and the database, where it helps the Java developers deal with the fundamental differences between their object oriented programming language and the relational database underneath it.




It strikes me as odd that there are so few tools to monitor the connections and the operations between Java programs and databases. Such tools are especially important in organisations where the database administrators and application developers are different departments there is a lot of miscommunication around databases and their performance.


We’ve all been in the classic argument, I’m sure. On one side, there are the database administrators, pooh-pooing the automatically generated tables and the quality of the SQL that the Java developers use. On the other side are the Java developers, bitching that they are being forced to do database-specific stuff and that databases should ‘just work’. Monitoring can help rationalise this discussion.


Before You Begin

For this tutorial I assume that you have a fully operational Zabbix server and that you have your monitoring set up for the JVM that runs your application. You are probably using the Java template already. If you have no monitor yet, please set that up before proceeding.


Steps to Take

Hibernate does not gather statistics by default. We first have to change the configuration of Hibernate to enable statistics gathering. Once that is done, we must hook up Hibernate’s statistics mbean to the session factory.


If your application was built using the Spring framework, you can skip writing the code. Instead, you can achieve the same using the Spring application wiring. Please note that you must use the exact same object name that was used for the template: “org.hibernate:type=statistics”.


Code to Write

In your hibernate configuration file, the one where you also configure the JDBC driver, switch on the property named “hibernate.generate_statistics”.

<property name="hibernate.generate_statistics">true</property>


Change the code where you create the Hibernate session factory. Attach the statistics service to the session factory as it is created. Assuming that you have some kind of factory method for the session factory, this code might look as shown below.

synchronized static SessionFactory getSessionFactory() {

    if (sessionFactory == null) {

        try {

            sessionFactory = new Configuration().configure()

                                         .buildSessionFactory();


            MBeanServer mbeanServer =

                     ManagementFactory.getPlatformMBeanServer();

                final ObjectName objectName = new ObjectName(

                               "org.hibernate:type=statistics");

                final StatisticsService mBean =

                                        new StatisticsService();

                mBean.setStatisticsEnabled(true);

                mBean.setSessionFactory(sessionFactory);

                mbeanServer.registerMBean(mBean, objectName);

            } catch (MalformedObjectNameException e) {

                log.error("unable to register mbean", e);

                throw new RuntimeException(e);

            } catch (InstanceAlreadyExistsException e) {

                log.error("unable to register mbean", e);

                throw new RuntimeException(e);

            } catch (MBeanRegistrationException e) {

                log.error("unable to register mbean", e);

                throw new RuntimeException(e);

            } catch (NotCompliantMBeanException e) {

                log.error("unable to register mbean", e);

                throw new RuntimeException(e);

            }

        }


        return sessionFactory;

    }


The object name you choose is of special interest. While you are certainly free to choose whatever name you like, the Zabbix template for Hibernate is hard-coded to expect the object name used in the sample above: “org.hibernate:type=statistics”. If you choose to use a different object name, use a text editor on the Hibernate template to correct all the object names.


The easiest way to test that the new mbean is available is to connect to your application using jconsole. The new mbean will show up under the tab named “MBeans”.


With this done, upload the file named “Template_Hibernate.xml” to Zabbix, and add that template to your JVM’s host definition.


Hibernate Template

The template tries to concentrate on only the core items relating to Hibernate. It attempts to assist you in tracking down two problems: SQL query storms and session leakage.


SQL Query Storms

A typical problem with naive object-relational mapping is that the Java application starts to generate massive volumes of relatively small queries. Typically, we see a search query that retrieves a row set, followed by a slew of queries, one for each element in the previous row set.


Such query storms are a result of the difference in philosophy in Java and in databases. In Java, each element in a set is regarded as a fully independent object. Such objects have their own, individual operations. In databases, the thinking is much more set-oriented. Operations in database always operate on whole sets of objects. Objects are never individuals, but always part of a larger group.


Actually tracking down query storms cannot be done using Zabbix. I regard SQL query storms as application bugs, to be tracked down by a team consists of a database administrator and a Java developer working together.


The Hibernate template help discover that an application suffers from query storms. It is useful to see if new releases of the application introduce such storms. To that end, we monitor the transaction rate as transitions per second.


Precisely how many transactions per second are sane and what rates are outrageous is completely application specific. My only advise here is to start monitoring the transaction rate, and see for yourself.


Session Leakage

A problem that frequently plagues new systems is that they leak database connections. This eventually exhausts the maximum number of connections that the database will accept.


In Hibernate, database connections are called sessions. To track connection leakage, we monitor the number of sessions opened and closed. Deciding that a connection leak is occurring is a little tricky.


Basically, if there is a difference between the number of sessions opened and the number of session that were closed, you may have a leak. However, the application will have a number of sessions open for legitimate business. You will have to look at the graph and see if the difference in opened and closed connections is stable, or if it grows over time. It it grows, you may well have spotted a connection leak.


Slow Queries

The items “slow query time” and “slow query sql” may assist in finding a particularly terrible query. It is only useful in smaller systems, because there is no way to determine the second-slowest query. I find that in practice, the query analysis tools found in databases are much more powerful to reveal dodgy SQL queries.

 
if you find this interesting, terrible or just would like to know more, e-mail memailto:kjkoster@kjkoster.org?subject=
web statistics
download zapcathttp://sourceforge.net/project/showfiles.php?group_id=209024
photo: Kenneth G. Libbrechthttp://www.its.caltech.edu/~atomic/snowcrystals/
http://java-monitor.com/