如何从 entitymanager 访问 Hibernate 统计信息?
Posted
技术标签:
【中文标题】如何从 entitymanager 访问 Hibernate 统计信息?【英文标题】:How do I access Hibernate statistics from an entitymanager? 【发布时间】:2012-12-15 21:45:40 【问题描述】:我正在使用 Spring 3.1.1.RELEASE、JUnit 4.8.1 和 Hibernate 4.1.5.Final。我正在尝试测试我的二级缓存是否配置正确,但不确定如何操作。我正在使用 JPA 实体管理器,像这样在 Spring 中配置...
<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>
我已经像这样配置了我的二级缓存......
<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>
在给定我的 javax.persistence.EntityManager 的情况下,如何访问 org.hibernate.stat.Statistics 对象?显然,我需要以某种方式访问 SessionFactory,但我不知道合适的演员阵容。
谢谢,- 戴夫
【问题讨论】:
【参考方案1】:您可以通过多种方式访问 Hibernate 统计信息:
以编程方式
如果你想在你的应用程序中获取Statistics
对象,你可以这样做:
Session session = entityManager.unwrap(Session.class);
Statistics statistics = session.getSessionFactory().getStatistics();
首先,我们将EntityManager
解包到Hibernate Session
,然后您可以通过关联的SesisonFactory
访问Syatistics
。
记录
如果还可以记录Statistics
报告,则需要添加如下日志配置项:
<logger name="org.hibernate.engine.internal.StatisticalLoggingSessionEventListener" level="info"/>
JMX
对于 Hibernate 5.4.2 及更高版本,您还可以通过 JMX 公开 Statistics
对象。
为此,您需要设置hibernate.jmx.enabled
配置属性:
<property name="hibernate.jmx.enabled" value="true"/>
并在您的 JMX 客户端应用程序中找到 org.hibernate.core
MBean 包。
【讨论】:
【参考方案2】:我过去曾为此苦苦挣扎:Exposing Hibernate (cache) statistics through JMX with Spring in Tomcat
如果您只是想知道“它是否正常工作”,您可以为 org.hibernate.stat.Statistics
或 org.hibernate.stat.*
启用 Hibernate 调试日志记录。但是,如果您(像我一样)想要一个缓存统计报告,您可以执行以下操作。这会公开一个包含所有统计信息的 JMX bean:
/**
* 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);
应用上下文:
<!-- 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" />
【讨论】:
【参考方案3】:实体管理器有一个名为 getDelegate 的方法。调用它并将其类型转换为休眠会话对象。一旦你有了休眠会话对象,你就可以获得会话工厂和统计信息。
【讨论】:
感谢您的提示。这给了我一个看的地方。现在可以使用entity manager
的 unwrap
方法。即Session session = em.unwrap(Session.class);
【参考方案4】:
最简单的方法是为您的 SessionFactory
定义一个 bean,然后将其自动装入。据我所知,没有直接的方法可以从 EntityManager
获取 SessionFactory
。
【讨论】:
不是很好,但是有办法:SessionFactory sessionFactory = ((HibernateEntityManagerFactory) entityManager.getEntityManagerFactory()).getSessionFactory();以上是关于如何从 entitymanager 访问 Hibernate 统计信息?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Symfony 单命令应用程序中访问 EntityManager?
EntityManager 应该如何在一个很好的解耦的服务层和数据访问层中使用?
我如何从 crudrepository 获取 entitymanager
如何设置 JPA EntityManager 查询的超时时间