Register Hibernate Statistics as MBean in Tomcat

Hibernate can track Session and SessionFactory usage and store statistics in the org.hibernate.stat.Statistics class. The statistics can be exposed as JMX MBean and accessed e.g. through Java VisualVM with VisualVM-MBeans plugin, bundled with Java 6 JDK.

In my case, I had to monitor an application developed with Hibernate 3.2 and Spring 2.0 deployed in Tomcat 5.5. I followed these manuals:
http://raibledesigns.com/wiki/Wiki.jsp?page=HibernateJMX
http://tomcat.apache.org/tomcat-5.5-doc/monitoring.html

but I was not able to:
– connect to the MBeanServer embedded in Tomcat remotely, although the JMX remote port was specified in Tomcat launch configuration, there was no process listening on.
– register the Hibernate StatisticsService MBean via Spring and see it in VisualVM, although there were c3p0 connection pool MBeans (magically registered somehow)

I peeked at the c3p0 source code (com.mchange.v2.c3p0.management.ActiveManagementCoordinator). They were using directly ManagementFactory.getPlatformMBeanServer() to obtain the MBean server reference and register their beans.

So I married two solutions posted in Matt Raible’s wiki:

  • tell Hibernate to gather statistics; set hibernate.generate_statistics property to true
  • declare Hibernate Statistics MBean in the Spring application context:
  •     <bean id="statisticsService" class="org.hibernate.jmx.StatisticsService">
            <property name="statisticsEnabled" value="true"/>
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    
  • Register Statistics MBean on application startup (don’t forget to add the listener to web.xml):
  • public class HibernateStatisticsPublisherListener implements ServletContextListener {
    
        private static final Log LOG = LogFactory.getLog(HibernateStatisticsPublisherListener.class);
    
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            ApplicationContext appCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(
                servletContextEvent.getServletContext());
    
            try {
                MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
                ObjectName on = new ObjectName("Hibernate:type=statistics");
                StatisticsService mBean = (StatisticsService) appCtx.getBean("statisticsService");
                mBeanServer.registerMBean(mBean, on);
            } catch (Exception e) {
                LOG.error("Error registering Hibernate StatisticsService in the MBean server", e);
            }
        }
    
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
        }
    }
    

Now, start your Tomcat, connect to the local process in the VisualVM (be sure you installed VisualVM-MBeans plugin) and enjoy statistics on the MBeans tab!

Advertisements