I'm running a java webapp (wicket 6.13) using Hibernate 4.3 and Guice 1.0
I'm trying to configure Hibernate so that I can access runtime information via the JMX framework.
I'm not using spring, can anyone indicate how I enable the JMX on hibernate 4.3 manually.
I've poked around the JmxService, JmxServiceInitiator, JmxServiceImpl, StandardServiceRegistryImpl
I've also found the following settings in AvailableSettings:
"hibernate.jmx.enabled";
"hibernate.jmx.usePlatformServer";
"hibernate.jmx.agentId";
"hibernate.jmx.defaultDomain";
"hibernate.jmx.sessionFactoryName";
I've added the jmx.enabled true setting to my hibernate.cfg.xml file but this has had no effect.
I'm still not sure how to go about this.
Any help much appreciated
seems to be a bug after refactoring in hibernate. see https://hibernate.atlassian.net/browse/HHH-6190 for details
Here's a workaround I've used, utilising a java dynamic proxy to represent the statistics interface from hibernate, and the default platform mbean server:
@MXBean
public interface StatisticsMXBean extends Statistics {
}
public void initStatistics(SessionFactory sessionFactory) {
ObjectName statsName = new ObjectName("org.hibernate:type=statistics");
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
final Statistics statistics = sessionFactory.getStatistics();
statistics.setStatisticsEnabled(true);
Object statisticsMBean = Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] { StatisticsMXBean.class }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(statistics, args);
}
});
mbeanServer.registerMBean(statisticsMBean, statsName);
}
My environment is Java 8, Spring Boot 1.4.0 (Spring 4.3.2 and Hibernate 5.0.9).
I grabbed the old StatisticsServiceMBean from Hibernate 3.2.7 and used it as a template to wrap the Statistics object from Hibernate 5 using JMX Annotations.
Works with the jconsole hibernate statistics plugin.
I'm sure if you're not using Spring, you can still do something similar.
So you don't have to type all this in if you are using Spring, here it is:
import javax.persistence.EntityManagerFactory;
import javax.servlet.ServletContext;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.SessionFactory;
import org.hibernate.stat.CollectionStatistics;
import org.hibernate.stat.EntityStatistics;
import org.hibernate.stat.QueryStatistics;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.stat.Statistics;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
@Component
@ManagedResource("Hibernate:application=Statistics")
public class HibernateStatisticsMBean implements InitializingBean {
@Autowired
private ServletContext servletContext;
private Statistics stats;
@Override
public void afterPropertiesSet() throws Exception {
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext);
EntityManagerFactory emf = (EntityManagerFactory) wac.getBean("entityManagerFactory");
SessionFactory sessionFactory = ((HibernateEntityManagerFactory) emf).getSessionFactory();
sessionFactory.getStatistics().setStatisticsEnabled(true);
this.stats = sessionFactory.getStatistics();
}
@ManagedOperation
public void clear() {
stats.clear();
}
@ManagedOperation
public EntityStatistics getEntityStatistics(String entityName) {
return stats.getEntityStatistics(entityName);
}
@ManagedOperation
public CollectionStatistics getCollectionStatistics(String role) {
return stats.getCollectionStatistics(role);
}
@ManagedOperation
public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName) {
return stats.getSecondLevelCacheStatistics(regionName);
}
@ManagedOperation
public QueryStatistics getQueryStatistics(String hql) {
return stats.getQueryStatistics(hql);
}
@ManagedAttribute
public long getEntityDeleteCount() {
return stats.getEntityDeleteCount();
}
@ManagedAttribute
public long getEntityInsertCount() {
return stats.getEntityInsertCount();
}
@ManagedAttribute
public long getEntityLoadCount() {
return stats.getEntityLoadCount();
}
@ManagedAttribute
public long getEntityFetchCount() {
return stats.getEntityFetchCount();
}
@ManagedAttribute
public long getEntityUpdateCount() {
return stats.getEntityUpdateCount();
}
@ManagedAttribute
public long getQueryExecutionCount() {
return stats.getQueryExecutionCount();
}
@ManagedAttribute
public long getQueryCacheHitCount() {
return stats.getQueryCacheHitCount();
}
@ManagedAttribute
public long getQueryExecutionMaxTime() {
return stats.getQueryExecutionMaxTime();
}
@ManagedAttribute
public long getQueryCacheMissCount() {
return stats.getQueryCacheMissCount();
}
@ManagedAttribute
public long getQueryCachePutCount() {
return stats.getQueryCachePutCount();
}
@ManagedAttribute
public long getFlushCount() {
return stats.getFlushCount();
}
@ManagedAttribute
public long getConnectCount() {
return stats.getConnectCount();
}
@ManagedAttribute
public long getSecondLevelCacheHitCount() {
return stats.getSecondLevelCacheHitCount();
}
@ManagedAttribute
public long getSecondLevelCacheMissCount() {
return stats.getSecondLevelCacheMissCount();
}
@ManagedAttribute
public long getSecondLevelCachePutCount() {
return stats.getSecondLevelCachePutCount();
}
@ManagedAttribute
public long getSessionCloseCount() {
return stats.getSessionCloseCount();
}
@ManagedAttribute
public long getSessionOpenCount() {
return stats.getSessionOpenCount();
}
@ManagedAttribute
public long getCollectionLoadCount() {
return stats.getCollectionLoadCount();
}
@ManagedAttribute
public long getCollectionFetchCount() {
return stats.getCollectionFetchCount();
}
@ManagedAttribute
public long getCollectionUpdateCount() {
return stats.getCollectionUpdateCount();
}
@ManagedAttribute
public long getCollectionRemoveCount() {
return stats.getCollectionRemoveCount();
}
@ManagedAttribute
public long getCollectionRecreateCount() {
return stats.getCollectionRecreateCount();
}
@ManagedAttribute
public long getStartTime() {
return stats.getStartTime();
}
@ManagedAttribute
public boolean isStatisticsEnabled() {
return stats.isStatisticsEnabled();
}
@ManagedOperation
public void setStatisticsEnabled(boolean enable) {
stats.setStatisticsEnabled(enable);
}
@ManagedOperation
public void logSummary() {
stats.logSummary();
}
@ManagedAttribute
public String[] getCollectionRoleNames() {
return stats.getCollectionRoleNames();
}
@ManagedAttribute
public String[] getEntityNames() {
return stats.getEntityNames();
}
@ManagedAttribute
public String[] getQueries() {
return stats.getQueries();
}
@ManagedAttribute
public String[] getSecondLevelCacheRegionNames() {
return stats.getSecondLevelCacheRegionNames();
}
@ManagedAttribute
public long getSuccessfulTransactionCount() {
return stats.getSuccessfulTransactionCount();
}
@ManagedAttribute
public long getTransactionCount() {
return stats.getTransactionCount();
}
@ManagedAttribute
public long getCloseStatementCount() {
return stats.getCloseStatementCount();
}
@ManagedAttribute
public long getPrepareStatementCount() {
return stats.getPrepareStatementCount();
}
@ManagedAttribute
public long getOptimisticFailureCount() {
return stats.getOptimisticFailureCount();
}
@ManagedAttribute
public String getQueryExecutionMaxTimeQueryString() {
return stats.getQueryExecutionMaxTimeQueryString();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With