Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hibernate jconsole spring configuration

I'm struggling to configure hibernate jmx in order to have some metrics with the hibernate jconsole plugin.

actually I followed the configuration from the official website of hibernate jconsole plugin: http://hibernate-jcons.sourceforge.net/usage.html#pre-requisites

but it doesn't work so I searched on internet for hours, tested things. the only relevant thing I found, related to my problem, is that: How to configure Hibernate statistics in Spring 3.0 application?

But It still doesn't work. I need your help.

here is the configuration:

@PersistenceContext(unitName = DomainConstants.JPA_PU_BACKEND)
private EntityManager em;

@Bean(name="jmxExporter")
public MBeanExporter    jmxExporter() throws MalformedObjectNameException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
    MBeanExporter exporter = new MBeanExporter();
    Map<String, Object> beans = new HashMap<String, Object>();
    beans.put("Hibernate:application=Statistics", "hibernateStatisticsBean");
    MBeanServerFactoryBean serverFactory = new MBeanServerFactoryBean();
    serverFactory.setLocateExistingServerIfPossible(true);
    // --- new1
    MBeanServer MBeanServer = serverFactory.getObject();
    exporter.setServer(MBeanServer);
    exporter.setRegistrationPolicy(RegistrationPolicy.REPLACE_EXISTING);
    // end -- new1
    exporter.setBeans(beans);
    return exporter;
}


@Bean(name="hibernateStatisticsBean")
public StatisticsService hibernateStatisticsBean() {
    StatisticsService service = new StatisticsService();
    service.setStatisticsEnabled(true);
    service.setSessionFactory(((Session)em.getDelegate()).getSessionFactory());
    return service;
}

I also set hibernate.generate_statistics to true to the hibernate configuration.

I'm stuck. I really need this tool to work since we have queries that take a lot of time. this tool would be perfect.

EDIT: The MBean seems to be loaded. the attributes change when I do queries. image2 http://imageshack.com/a/img838/5904/dj8c.png

But when I tried to invoke one of the operations: getQueryStatistics, getCollectionStatistics etc.. I get the following error: image1 http://imageshack.com/a/img838/9693/ibkd.png

And actually I have no stats about the queries, nothing displayed: image3 http://imageshack.com/a/img835/8088/laoz.png

like image 702
Jeremy S. Avatar asked May 02 '14 09:05

Jeremy S.


2 Answers

I know this post is two years old, but I wanted to share this in case other people have been having trouble getting the Hibernate JConsole plugin working with the latest Spring and Hibernate.

My environment is Java 8, Spring Boot 1.4.0 (Spring 4.3.2 and Hibernate 5.0.9).

I tried several different things that people mentioned worked for them in Hibernate 4.3, but they didn't work for me. Finally, I decided to take some advice from someone else I found in the Hibernate feature request forums (asking to bring back JMX support for Hibernate Statistics) who suggested grabbing the old StatisticsServiceMBean from Hibernate 3.2.7.

I updated the MBean and used it to wrap the Statistics object from Hibernate 5 using JMX Annotations, and of course it worked.

So you don't have to type all this in, 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();
    }

}
like image 191
Chris Jensen Avatar answered Oct 27 '22 00:10

Chris Jensen


Great answer from @Chris Jensen

In my case I needed to tweak it a little to make it working:

...
@Component
@ManagedResource("Hibernate:application=Statistics")
public class HibernateStatisticsMBean implements InitializingBean {

@Autowired
private EntityManagerFactory entityManagerFactory;

private Statistics stats;

@Override
public void afterPropertiesSet() throws Exception {
    SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
    sessionFactory.getStatistics().setStatisticsEnabled(true);
    this.stats = sessionFactory.getStatistics();
}
...
like image 30
Martin Patsov Avatar answered Oct 26 '22 22:10

Martin Patsov