Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 2 - Enabling JMX Monitoring on Hibernate v3 and Ehcache 1.3.0 on "HibernateTutorialApp"
Posted by maxpoon on June 27, 2007 at 09:12 AM
Background
Apart from showing quite an example of easy enhancement of JSF-based web application as discussed earlier in "Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 1 - Co-ordinating Query Views Based on Parameter Passing from JSF View to Managed Bean", the NetBeans tutorial JSF-JPA-Hibernate application created ('SimpleJpaHibernateApp') can also be easily extended to demonstrate JMX monitoring on Hibernate v3 and the latest Ehcache 1.3.0 - the respective very common open source Java object/relational persistence and caching implementations, which have also included support for JMX to enable monitoring on their operational states and statistics, including the overall (e.g. query and 2nd level cache) cache hit/miss statistics, time of the slowest query (from Hibernate v3), and individual cache hit/miss statistics (from Ehcache 1.3.0).
These monitoring capabilities give very helpful information for application developers and administrators to understand actual behaviour of their applications deployed, for resource usage optimisation and performance tuning.
The following shows the configurations to use Ehcache 1.3.0, followed by configurations of JMX monitoring on Hibernate v3 and Ehcache 1.3.0, for both :
Hibernate Core v3 applications
JPA-with-Hibernate applications
Since JMX monitoring configuration :
on Ehcache requires the latest Ehcache 1.3.0 on JPA-with-Hibernate application is also based on the configuration for Hibernate Core v3 application
we shall proceed in the following sequence :
and (3) and (4) above will be discussed in next article "Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 3 - Enabling JMX Monitoring on Hibernate v3 and Ehcache 1.3, on SimpleJpaHibernateApp".
Software Requirements
(1) Configuring HibernateTutorialApp/HibernateTravelPOJO to use Ehcache 1.3.0
As HibernateTutorialApp actually uses another application 'HibernateTravelPOJO' supplied (in zip archive
HibernateTravelPOJO.zip) in the tutorial for its persistence POJOs, configuration to use Ehcache 1.3.0 (instead of any earlier Ehcache version bundled with Hibernate) should be done in HibernateTravelPOJO.
Figure 1.0 - Contents of the HibernateTravelPOJO Project
There are 2 cases for the configuration of HibernateTravelPOJO to use Ehcache 1.3.0 :
Case 1 : If you have already set up HibernateTravelPOJO and HibernateTutorialApp according to the NetBeans tutorial "
Using Hibernate With the NetBeans Visual Web Pack", you may just need to replace any previous version of the
ehcache-*.jar file used (as specified in the Netbeans "Hibernate322" Class Library in the tutorial) with the
ehcache-1.3.0.jar from Ehcache1.3.0 downloaded, then skip to
Step 1.4 below.
Case 2 : If you are just going to set up HibernateTravelPOJO and HibernateTutorialApp, you can start with
Step 1.1 below to set up HibernateTravelPOJO and HibernateTutorialApp to use the current latest Hibernate 3.2.4sp1 and Ehcache 1.3.0.
Step 1.1 - Create Hibernate Class Library in NetBeans IDE
First, follow the original NetBeans tutorial "
Using Hibernate With the NetBeans Visual Web Pack" section "
Create a Hibernate Class Library" to create Class Library for Hibernate in NetBeans IDE. Since the latest Hibernate 3.2.4.sp1 is available (as at time of writing this article), it can be used in place of Hibernate 3.2.2 suggested in the tutorial, also referring to
Figure 1.1 below for the list of jar files to be included for the NetBeans Class Library "Hibernate3.2.4sp1".
Figure 1.1 - Create HibernateCore3.2.4sp1 Class Library in NetBeans IDE
Step 1.2 - Create "Ehcache-1.3.0" Class Library in NetBeans IDE
Download the latest Ehcache 1.3.0 (now including JMX support) from
here, unzip it, and create new NetBeans Class Library "Ehcache-1.3.0" as shown:
Figure 1.2.1 - Create new "Ehcache-1.3.0" Class Library for NetBeans IDE
Figure 1.2.2 - Add ehcache-1.3.0.jar to the new "Ehcache-1.3.0" Class Library
Step 1.3 - Configure HibernateTravelPOJO to use Ehcache 1.3.0
Follow the steps of "
Using Hibernate With the NetBeans Visual Web Pack" to set it up, but with the our new NetBeans Class Libraries "HibernateCore3.2.4sp1" and "Ehcache-1.3.0" as follows.
Figure 1.3 - Add Library "Ehcache-1.3.0" to HibernateTravelPOJO
Step 1.4 - Configure Hibernate to use Ehcache 1.3.0
To configure Hibernate v3 to use Ehcache 1.3.0, we shall start with modifying the Hibernate configuration file
hibernate.cfg.xml as shown in
Code Listing 1.4.1 (additional settings required in
bold) to enable Hibernate 2nd-level caching using Ehcache on the following classes and collection for HibernateTravelPOJO :
Class hibernatetravelpojo.Person with read-write mode Class hibernatetravelpojo.Trip with read-write mode Collection hibernatetravelpojo.Person.trips with read-write mode
Meanwhile, we also need to modify the Hibernate mapping files
hibernatetravelpojo/Person.hbm.xml hibernatetravelpojo/Trip.hbm.xml
as shown in
Code Listing 1.4.2 and
Code Listing 1.4.3 (again, additional settings required in
bold).
Code Listing 1.4.1 - Modified hibernate.cfg.xml for HibernateTravelPOJO
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Data Source Name -->
<property name="hibernate.connection.driver_class">
org.apache.derby.jdbc.ClientDriver</property>
<property name="hibernate.connection.url">
jdbc:derby://localhost:1527/travel</property>
<property name="hibernate.connection.username">travel</property>
<property name="hibernate.connection.password">travel</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">
org.hibernate.dialect.DerbyDialect</property>
<!-- Debug logging of SQL statements -->
<property name="hibernate.show_sql">true</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Enable Hibernate statistics generation -->
<property name="hibernate.generate_statistics">true</property>
<!-- Cache Configurations -->
<!-- Using net.sf.ehcache.hibernate.SingletonEhCacheProvider instead of
net.sf.ehcache.hibernate.EhCacheProvider ensures the same instance
of CacheManager is referred to by both Hibernate and our JMX Agent
simpleJpaHibernateApp.agents.jmxAgent. (Thanks to Greg Luck!) -->
<property name="hibernate.cache.provider_class">
net.sf.ehcache.hibernate.SingletonEhCacheProvider</property>
<property name="hibernate.cache.provider_configuration">
/ehcache.cfg.xml</property>
<property name="hibernate.cache.use_minimal_puts">false</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_structured_entries">true</property>
<!-- Mapping Files -->
<mapping resource="hibernatetravelpojo/Person.hbm.xml"/>
<mapping resource="hibernatetravelpojo/Trip.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Coding Listing 1.4.2 - Modified Person.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernatetravelpojo.Person" table="PERSON">
<!-- Class Cache -->
<cache usage="read-write"/>
<!-- Primary Key -->
<id name="personId" column="PERSONID">
<generator class="increment"/>
</id>
<!-- Direct Data Properties -->
<property name="name"
column="NAME"/>
<property name="jobTitle"
column="JOBTITLE"/>
<property name="frequentFlyer"
column="FREQUENTFLYER"/>
<!-- Relationship References -->
<set name="trips" table="TRIP" lazy="true" inverse="true"
cascade="all-delete-orphan">
<!-- Collection Cache -->
<cache usage="read-write"/>
<key column="PERSONID"/>
<one-to-many class="hibernatetravelpojo.Trip"/>
</set>
</class>
</hibernate-mapping>
Code Listing 1.4.3 - Modified Trip.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernatetravelpojo.Trip" table="TRIP">
<!-- Class Cache -->
<cache usage="read-write"/>
<!-- Primary Key -->
<id name="tripId" column="TRIPID">
<generator class="increment"/>
</id>
<!-- Direct Data Properties -->
<property name="personId"
column="PERSONID"/>
<property name="depDate"
column="DEPDATE"
type="date"/>
<property name="depCity"
column="DEPCITY"/>
<property name="destCity"
column="DESTCITY"/>
<property name="tripTypeId"
column="TRIPTYPEID"/>
</class>
</hibernate-mapping>
Also, the following Ehcache configuration file
ehcache.cfg.xml is required in the root of Java source directory together with
hibernate.cfg.xml.
Code Listing 1.4.4 - ehcache.cfg.xml for HibernateTravelPOJO
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="hibernatetravelpojo.Person"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
<cache name="hibernatetravelpojo.Trip"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
<cache name="hibernatetravelpojo.Person.trips"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
</ehcache>
With the above configuration, compile the project HibernateTutorialApp and run in NetBeans IDE, right-click on HibernateTutorialApp project and select [Clean and Build], then [Deploy Project], followed by [Run Project], giving the following
Figure 1.4 - HibernateTutorialApp with inital Trip query for Person "Able, Tony"
(2) Configure JMX Monitoring for HibernateTutorialApp/HibernateTravelPOJO
Enabling JMX monitoring for an application typically involves the creation of following :
JMX MBean - which can represent a device, an application, or any resource that needs to be managed. JMX Agent - which is an application that registers MBean(s) with a MBeanServer, e.g. the platform MBeanServer.
In case of Hibernate, the MBean is provided via :
followed by MBean registration via :
where objectName is your assigned registration ObjectName for statMBean on the instance of
MBeanServer.
In case of Ehcache, four types of 'pre-fabricated' MBeans have already been provided, including :
CacheManager MBean
Cache MBean CacheConfiguration MBeans CacheStatistics MBeans
together with
net.sf.ehcache.management.ManagementService which provides convenient registration (instead of individual handling) of all these four MBeans for the instance of
CacheManager being used :
where registerCacheManger, registerCache, registerCacheConfiguration, registerCacheStatistics are the boolean flags to indicate whether the respective MBeans are to be registered, under the ObjectName domain
net.sf.ehcache.
Hence, to enable JMX monitoring on Hibernate and Ehcache, we simply need to create a JMX Agent that registers the appropriate Hibernate and Ehcache MBeans with our MBeanServer.
Step 2.1 - Create JMX Agent with Hibernate and Ehcache MBeans Registration Codes
First, open the HibernateTravelPOJO project in NetBeans IDE, and create our new JMX Agent (as shown in
Figure 2.1.1), specifying it as "JmxAgent" inside the package "hibernatetravelpojo.agents" (as shown in
Figure 2.1.2), followed by Adding JMX registration code (as shown in
Figure 2.1.3).
Figure 2.1.1 - Creating file with type "JMX Agent" under "Management" Category
Figure 2.1.2 - Specifying the new 'JmxAgent' in package 'hibernatetravelpojo'
Figure 2.1.3 - Adding MBeans registration codes for Hibernate and Ehcache in JmxAgent
The additional MBean registration codes are highlighted in
bold in the following code listing.
Also, we need to modify the
getDefault method (also as highlighted in
bold) to take the
SessionFactory as parameter from the calling context instead of getting it again.
Code Listing 2.1 - JmxAgent.java (Hibernate and Ehcache MBeans registration codes in bold)
/*
* JmxAgent.java
*
*/
package hibernatetravelpojo;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.management.ManagementService;
import org.hibernate.SessionFactory;
import org.hibernate.jmx.StatisticsService;
/**
* JMX agent (singleton) for monitoring Hibernate and Ehcache in the
* 'extended' HibernateTravelPOJO example application from NetBeans
* tutorial "Using Hibernate With the NetBeans Visual Web Pack"
* at http://www.netbeans.org/kb/55/vwp-hibernate.html, which uses:
* <ul>
* <li>JavaServer Faces (JSF) web-tier</li>
* <li>Hibernate Core (3.2.4.sp1)</li>
* <li>Ehcache 1.3.0</li>
* </ul>
*
* @author Max Poon (maxpoon@dev.java.net)
*/
public class JmxAgent {
/**
* Register MBeans, enable Hibernate & Ehcache JMX Statistics
* @param sf org.hibernate.SessionFactory to be passed in from
* the invoking context (instead of creating it again
* here which is expensive operation)
*/
public void init(SessionFactory sf) throws Exception {
// Define ObjectName of the MBean
ObjectName on = new ObjectName
("Hibernate:type=statistics,application=HibernateTravelPOJO");
// Enable Hibernate JMX Statistics
StatisticsService statsMBean = new StatisticsService();
statsMBean.setSessionFactory(sf);
statsMBean.setStatisticsEnabled(true);
mbs.registerMBean(statsMBean, on);
/**
* Enable Ehcache JMX Statistics
* Use CacheManager.getInstance() instead of new CacheManager()
* as net.sf.ehcache.hibernate.SingletonEhCacheProvider is used
* to ensure reference to the same CacheManager instance as used
* by Hibernate
*/
CacheManager cacheMgr = CacheManager.getInstance();
ManagementService.registerMBeans
(cacheMgr, mbs, true, true, true, true);
}
/**
* Returns an agent singleton.
*/
public synchronized static JmxAgent getDefault(SessionFactory sf)
throws Exception {
if(singleton == null) {
singleton = new JmxAgent();
singleton.init(sf);
}
return singleton;
}
public MBeanServer getMBeanServer() {
return mbs;
}
// Platform MBeanServer used to register your MBeans
private final MBeanServer mbs =
ManagementFactory.getPlatformMBeanServer();
// Singleton instance
private static JmxAgent singleton;
}
Step 2.2 - Modify HibernateUtil.java to initiate JMX Agent
We need to instantiate the JMX Agent somewhere, in case applications such as HibernateTravelPOJO which uses hibernatetravelpojo.HibernateUtil to get the Hibernate SessionFactory, HibernateUtil is a good place to do it.
Code Listing 2.2 - hibernatetravelpojo.HibernateUtil.java with modifications needed in bold
package hibernatetravelpojo;
import org.hibernate.*;
import org.hibernate.cfg.*;
/**
* HibernateUtil.java of HibernateTravelPOJO example application from
* NetBeans tutorial "Using Hibernate With the NetBeans Visual Web Pack"
* at http://www.netbeans.org/kb/55/vwp-hibernate.html
*
* @author Max Poon (maxpoon@dev.java.net)
*/
public class HibernateUtil {
private static final SessionFactory sf;
static {
try {
// Create the SessionFactory
sf = new Configuration().configure().buildSessionFactory();
// Initiate JMX Agent
JmxAgent.getDefault(sf);
} catch (Throwable ex) {
// Ensure you log the exception somehow, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sf;
}
}
Now, HibernateTutorialApp can be recompiled by right-clicking on [HibernateTutorialApp] project in NetBeans IDE and selecting [Clean and Build Project] (which automatically recompiles HibernateTravelPOJO), and tested by :
requesting http://localhost:port/HibernateTutorialApp in browser, or right-click on the [HibernateTutorialApp] project in NetBeans IDE and select [Run Project]
to observe that shown in
Figure 1.4 again, and to try querying the
Trip's for the other
Person's.
The application should now be executing successfully so it is ready for observation of JMX metrics in the following
Step 2.3.
In case of problems, the application server server log can be checked.
Step 2.3 - Use JConsole to Observe JMX Statistics
Start
JConsole and connect to the JVM running GlassFish (indicated by "com.sun.enterprise.server.PELaunch" in JConsole) via JMX Dynamic Attach :
Figure 2.3.0 - JConsole attaching to JVM running GlassFish (com.sun.enterprise.server.PELaunch) via JMX Dynamic Attach
Go to JConsole [MBeans] and expand on [Hibernate>statistics>HibernateTravelPOJO>Attributes] to view Hibernate Statistics (as shown in
Figure 2.3.1) which include :
Collection Statistics
Role Names, Fetch Count, Load Count, Recreate Count, Remove Count, Update Count
Entity Statistics
Entity Names, Delete Count, Fetch Count, Insert Count, Load Count, Update Count
Query Statistics
Queries, Hit Count, Miss Count, Cache Put Count, Execution Count, Execution Max Time, Execution Max Time Query String
Second Level Cache Statistics
Cache Region Names, Cache Hit Count, Cache Miss Count, Cache Put Count
Session and Transaction Counts
SessionFactory JNDI Names, Session Open Count, Session Close Count, Transaction Count
Figure 2.3.1 - JConsole showing Hibernate Statistics for HibernateTravelPOJO
Note that the statistics as shown in the Figure 2.3.1 agrees with the HibernateTutorialApp's invocation of initial query page which retrieves 5
Trip instances for the "Able, Tony"
Person instance of as shown in
Figure 1.4, :
* EntityLoadCount = 11
=> HibernateTutorialApp's
Page1#prerender() (as shown in
Code Listing 2.3.1) invoking :
SessionBean1.getPersonOptions()
to load all 6 available instances of Person available.
SessionBean1.getTripDataProvider().refreshTripsList(
new Integer((String)firstPerson.getValue()) )
to load all 5 available instances of Trip available for the "Able, Tony" Person instance
* CollectionLoadCount = 1
=> HibernateTutorialApps's
Page1#prerender() (as shown in
Code Listing 2.3.1) invoking :
SessionBean1.getTripDataProvider().refreshTripsList(
new Integer((String)firstPerson.getValue()) )
to load 1 collection of instances of Trip available for the "Able, Tony" Person instance
* SecondLevelCachePutCount = EntityLoadCount + CollectionLoadCount = 12
as the loaded entities and collection are put into the respective caches
Code Listing 2.3.1 - Page1#prerender() method
...
public void prerender() {
try {
if (dropDown1.getSelected() == null ) {
SessionBean1 sb1 = getSessionBean1();
if (sb1 == null) {
log("Null \"SessionBean1\" from Page1#prerender()");
} else {
Option[] personOptions = sb1.getPersonOptions();
if (personOptions == null) {
log("Null \"PersonOptions\" from Page1#prerender()");
} else {
Option firstPerson = personOptions[0];
sb1.getTripDataProvider().refreshTripsList(
new Integer((String)firstPerson.getValue()));
}
}
}
} catch (Exception ex) {
log("Error Description", ex);
error(ex.getMessage());
}
}
...
The cache configurations for each of the Entity Cache are available via the Ehcache CacheConfiguration MBeans, e.g. as shown for
Person in Figure 2.3.2.
Figure 2.3.2 - JConsole showing Ehcache CacheConfiguration for hibernatetravelpojo.Person
While, individual cache statistics (e.g. for entity, collection, query, and 2nd level cache) should be available programmatically from Hibernate JMX statistics, e.g.
various cache statistics are available directly from Ehcache as MBean attributes for display by JConsole without need for further programmatic retrieval, as shown in
Figure 2.3.3 for class cache for Person Figure 2.3.4 for class cache for Trip Figure 2.3.5 for collection cache for PersonTrip Figure 2.3.6 for StandardQueryCache (showing it not being used)
Figure 2.3.7 for Ehcache Cache and CacheManager Operations
per Cache operations : flush(), removeAll() CacheManager operations : clearAll(), getCache(), shutdown()
Code Listing 2.3.2a - Getting individual Entity Counts Statistics from Hibernate
...
StatisticsService statsMBean = new StatisticsService();
statsMBean.setSessionFactory(sf);
statsMBean.setStatisticsEnabled(true);
String[] entityNames = statsMBean.getEntityNames();
for (String entityName : entityNames) {
EntityStatistics entityStats =
StatisticsService.getEntityStatistics(entityName);
long loadCount = entityStats.getLoadCount();
long fetchCount = entityStats.getFetchCount();
long insertCount = entityStats.getInsertCount();
long updateCount = entityStats.getUpdateCount();
long deleteCount = entityStats.getDeleteCount();
long optimisticFailureCount = entityStats.getOptimisticFailureCount();
...
}
...
Code Listing 2.3.2b - Getting individual 2nd Level Cache Statistics from Hibernate
...
String[] cacheNames = statsMBean.getSecondLevelCacheRegionNames();
for (String cacheName : cacheNames) {
SecondLevelCacheStatistics cacheStats =
StatisticsService.getSecondLevelCacheStatistics(cacheName);
long hitCount = cacheStats.getHitCount();
long missCount = cacheStats.getMissCount();
long putCount = cacheStats.getPutCount();
long sizeInMemory = cacheStats.getSizeInMemory();
...
}
...
Figure 2.3.3 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person
Figure 2.3.4 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Trip
Figure 2.3.5 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person.trips
Figure 2.3.6 - JConsole showing Ehcache CacheStatistics for StandardQueryCache
Figure 2.3.7 - JConsole showing Ehcache Cache and CacheManager Operations
It can be shown that retrieving the 6
Trip's for 2nd
Person "Black, John" :
Figure 2.3.8 - HibernateTutorialApp with Trip query for 2nd Person "Black, John"
causes more cache misses and put, as shown in :
Figure 2.3.9 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person on querying the Trip's for the 2nd Person "Black, John"
Figure 2.3.10 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Trip on querying the Trip's for the 2nd Person "Black, John"
Figure 2.3.11 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person.trips on querying the Trip's for the 2nd Person"Black, John"
It can also be shown that retrieval of
Trip's for "Able, Tony" again but after expiry of the cache's
TimeToIdleSeconds still causes cache misses as shown in :
Figure 2.3.12 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person on querying the Trip's for the 1st Person "Able, Tony" again but after cache expiry
Figure 2.3.13 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Trip on querying the Trip's for the 1st Person "Able, Tony" again but after cache expiry
Figure 2.3.14 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person.trips on querying the Trip's for the 1st Person "Able, Tony" again but after cache expiry
Finally, it can be shown that retrieval of (the 2nd)
Person "Black, John" and then on (the 1st)
Person "Able, Tony" again within expiry period, now generates cache hits as shown in :
Figure 2.3.15 for class cache for Person, for the "Able, Tony" which was cached already
Figure 2.3.16 for class cache for Trip, for the 5 instances of Trip's cache
Figure 2.3.17 for collection cache for PersonTrip, for the collecton cache
Figure 2.3.15 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person on querying the Trip's for the 1st Person "Able, Tony" again before cache expiry
Figure 2.3.16 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Trip on querying the Trip's for the 1st Person "Able, Tony" again before cache expiry
Figure 2.3.17 - JConsole showing Ehcache CacheStatistics for hibernatetravelpojo.Person.trips on querying the Trip's for the 1st Person "Able, Tony" again before cache expiry
Finally, the Ehcache statistics observed above match with the Hibernate statistics as shown in
Figure 2.3.18.
Figure 2.3.18 - JConsole showing Hibernate Statistics after retrieval for Trip's for the 1st Person "Able, Tony", then 2nd Person "Black, John", then 1st Person again after cache expiry, followed by retrieval of 2nd and then 1st Person again before cache expiry to show cache hits.
Achieving the above indicates that JMX monitoring on Hibernate v3 and Ehcache 1.3.0 is working in your copy of HibernateTutorialApp. Enabling JMX monitoring on Hibernate and Ehcache can similarly be done on applications using JPA with Hibernate as shown in the next article "Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 3 - Enabling JMX Monitoring on Hibernate v3 and Ehcache 1.3, on SimpleJpaHibernateApp".
Bookmark blog post:
del.icio.us
Digg
DZone
Furl
Reddit