How do I access Hibernate statistics from an entitymanager?

Dave picture Dave · Dec 31, 2012 · Viewed 9.6k times · Source

I'm using Spring 3.1.1.RELEASE, JUnit 4.8.1, and Hibernate 4.1.5.Final. I'm trying to test whether my second level cache is configured correctly, but am unsure of how to do it. I'm using the JPA entity manager, configured in Spring like so ...

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaDialect">
        <bean class="org.collegeboard.springboard.core.jpa.HibernateJpaDialect">
            <property name="flushMode" value="COMMIT"/>
        </bean>
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="persistenceXmlLocation" value="classpath:META-INF/test-persistence.xml"/>
    <property name="persistenceUnitName" value="orgTestingDatabase"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="sharedEntityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
   <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

I have configured my second level cache like so ...

    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 
    <!--  Collect stats, this is for testing if the cache is working -->
    <property name="hibernate.generate_statistics">true</property>

How do I access a org.hibernate.stat.Statistics object given my javax.persistence.EntityManager ? Evidently, I need to access a SessionFactory somehow, but I can't figure out the appropriate series of casts.

Thanks, - Dave

Answer

Marcel St&#246;r picture Marcel Stör · Jan 1, 2013

I was wrestling with this in the past: Exposing Hibernate (cache) statistics through JMX with Spring in Tomcat

If you simply want to know "if it's working" you could enable Hibernate debug logging for org.hibernate.stat.Statistics or org.hibernate.stat.*. However, if you (like I) want to have a cache statistics report you could do something like the following. This exposes a JMX bean with all the stats:

/**
 * Provides code to register Hibernate's 2nd level cache statistics bean with a
 * JMX MBean server. Assumes that both the MBeanServer and the
 * EntityManagerFactory are available as Spring-managed beans. Note that while
 * registering this class enables the collection of statistics even if that was
 * previously disabled.
 */
public class HibernateCacheStatisticsJmxRegistration {

  @Autowired
  private EntityManagerFactory entityManagerFactory;

  @Autowired
  private MBeanServer mbeanServer;

  private ObjectName objectName;

  /**
   * Registers the statistics MBean that wraps a Hibernate session factory.
   * 
   * @throws JMException if anything fails..
   * @see HibernateCacheStatisticsJmxRegistration#unregister()
   */
  public void register() throws JMException {
    final SessionFactory sessionFactory = ((HibernateEntityManagerFactory) entityManagerFactory).getSessionFactory();

    objectName = new ObjectName("net.sf.ehcache:type=CacheStatistics,name=Hibernate2ndLevelCache");

    final StatisticsService statsMBean = new StatisticsService();
    statsMBean.setSessionFactory(sessionFactory);
    statsMBean.setStatisticsEnabled(true);
    mbeanServer.registerMBean(statsMBean, objectName);
  }

  /**
   * Unregisters the MBean that was registered.
   * 
   * @throws JMException if the de-registration fails
   * @see HibernateCacheStatisticsJmxRegistration#register()
   */
  public void unregister() throws JMException {
    mbeanServer.unregisterMBean(objectName);
  }
}

The app context:

<!-- Setting up Ehcache manager for various caches. -->
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
  <property name="configLocation" value="classpath:ehcache.xml" />
</bean>  
<ehcache:annotation-driven cache-manager="ehCacheManager" />

<!-- Exposing cache statistics through JMX. -->
<context:mbean-server />
<bean class="net.sf.ehcache.management.ManagementService" init-method="init">
  <constructor-arg ref="ehCacheManager"/>
  <constructor-arg ref="mbeanServer"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
</bean>    
<bean class="HibernateCacheStatisticsJmxRegistration" init-method="register" destroy-method="unregister" />