 |
Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 3 - Enabling JMX Monitoring on Hibernate v3 and Ehcache 1.3.0 on "SimpleJpaHibernateApp"
Posted by maxpoon on June 27, 2007 at 11:21 AM | Comments (0)
Background
This is the continuation from the
previous article "Extending
the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 2 - Enabling
JMX Monitoring on Hibernate v3 and Ehcache 1.3, on HibernateTutorialApp"
where we continue with (3) and (4) of the following :
- Configuring
HibernateTutorialApp/HibernateTravelPOJO to use Ehcache 1.3.0
- Configuring
HibernateTutorialApp/HibernateTravelPOJO to enable JMX monitoring on
Hibernate and Ehcache
- Configuring
SimpleJpaHibernateApp to use Ehcache 1.3.0
- Configuring
SimpleJpaHibernateApp to enable JMX monitoring on
Hibernate and Ehcache
(3)
Configuring
SimpleJpaHibernateApp to use Ehcache 1.3.0
The configurations for SimpleJpaHibernateApp to use Ehcache 1.3.0 are
similar to those of "Configuring
HibernateTutorialApp/HibernateTravelPOJO to use Ehcache 1.3.0" ,
except :
- SimpleJpaHibernateApp is directly configured to use Hibernate
(Hibernate-3.2.2, or above, e.g.
Hibernate-3.2.4sp1) and Ehcache-1.3.0
- persistence.xml and hibernate.cfg.xml (cache
related configurations highlighted in bold), and ehcache.cfg.xml as shown :
| Code Listing 3.1 - persistence.xml for
SimpleJpaHibernateApp |
<?xml version="1.0"
encoding="UTF-8"?>
<persistence
version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit
name="SimpleJpaHibernateAppPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/sample</jta-data-source>
<class>simpleJpaHibernateApp.entities.ProductCode</class>
<class>simpleJpaHibernateApp.entities.Product</class>
<class>simpleJpaHibernateApp.entities.Manufacturer</class>
<properties>
<property name=
"hibernate.ejb.classcache.simpleJpaHibernateApp.entities.ProductCode"
value="read-write"/>
<property name=
"hibernate.ejb.classcache.simpleJpaHibernateApp.entities.Product"
value="read-write"/>
<property name=
"hibernate.ejb.classcache.simpleJpaHibernateApp.entities.Manufacturer"
value="read-write"/>
<property name="hibernate.ejb.cfgfile"
value="/hibernate.cfg.xml"/>
</properties>
</persistence-unit>
</persistence> |
Code Listing 3.2 - hibernate.cfg.xml for
SimpleJpaHibernateApp
|
<?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>
<!--
SQL dialect -->
<property name="hibernate.dialect">
org.hibernate.dialect.DerbyDialect</property>
<!--
Debug logging of SQL statements -->
<property name="hibernate.show_sql">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>
</session-factory>
</hibernate-configuration>
|
| Coding Listing 3.3 - ehcache.cfg.xml for
SimpleJpaHibernateApp |
<?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="simpleJpaHibernateApp.entities.ProductCode"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
<cache name="simpleJpaHibernateApp.entities.Product"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
<cache name="simpleJpaHibernateApp.entities.Manufacturer"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
<cache
name="simpleJpaHibernateApp.entities.ProductCode.productCollection"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
<cache
name="simpleJpaHibernateApp.entities.Manufacturer.productCollection"
maxElementsInMemory="300"
eternal="true"
overflowToDisk="false"
/>
</ehcache>
|
(4)
Configuring SimpleJpaHibernateApp to enable JMX monitoring on
Hibernate and Ehcache
After being configured to use Ehcache 1.3.0 as shown in "Configuring
SimpleJpaHibernateApp to use Ehcache 1.3.0" above, the
SimpleJpaHibernateApp can be "Using
Hibernate With the Java Persistence API" can also be extended to
enable JMX monitoring, e.g. on Hibernate and Ehcache used, similar to "Configuring
HibernateTutorialApp/HibernateTravelPOJO to enable JMX monitoring on
Hibernate and Ehcache" in previous article.
Step 4.1 - Create JMX Agent with Hibernate and Ehcache MBeans
Registration Codes
Similar to Step 2.1
in "Configuring
HibernateTutorialApp/HibernateTravelPOJO to enable JMX monitoring on
Hibernate and Ehcache", we need to create the JMX Agent which
registers the Hibernate
and Ehcache MBeans to enable JMX monitoring on them. However,
there are a few small but important differences here...
(A) To register Hibernate's MBean, we still need the following codes :
// Enable Hibernate JMX Statistics
StatisticsService statsMBean = new StatisticsService();
statsMBean.setSessionFactory(sessionFactory);
statsMBean.setStatisticsEnabled(true);
mbs.registerMBean(statsMBean, on);
i.e. we need to get Hibernate SessionFactory from our JPA
execution environment (which uses the implementation-independent JPA PersistentUnit and the associated EntityMangerFactory instead) to
enable JMX monitoring on Hibernate, by (also used by the NetBeans
Tutorial "NetBeans
Wiki - UsingHibernateWithJPA") :
- Session
session = (Session) em.getDelegate();
And, in our case for SimpleJpaHibernateApp, it is followed by :
- SessionFactory
sessionFactory = session.getSessionFactory();
to get SessionFactory as in Code Listing
4.1 (additional MBeans registration codes in bold) below.
(B) Also, we would like to modify the init() method to take EntityMangerFactory from the
calling context, to get the Hibernate SessionFactory for registering
Hibernate statsMBean.
Code Listing 4.1 - SimpleJpaHibernateApp's
JmxAgent.java
|
/*
* JmxAgent.java
*
*/
package
simpleJpaHibernateApp.agents;
import
java.lang.management.ManagementFactory;
import
javax.management.MBeanServer;
import
javax.management.ObjectName;
import
javax.persistence.EntityManagerFactory;
import
javax.persistence.EntityManager;
import
net.sf.ehcache.CacheManager;
import
net.sf.ehcache.management.ManagementService;
import
org.hibernate.Session;
import
org.hibernate.SessionFactory;
import
org.hibernate.jmx.StatisticsService;
/**
* JMX agent
(singleton) for monitoring Hibernate and Ehcache
* in
SimpleJpaHibernateApp, which uses:
* <ul>
*
<li>JavaServer Faces (JSF) web-tier</li>
* <li>Java
Persistence API (JPA) persistence</li>
* <li>Hibernate
Core (3.2.4 sp1) and Hibernate EntityManager (3.3.1)</li>
* <li>Ehcache
1.3.0</li>
* </ul>
*
* @author Max Poon
(maxpoon@dev.java.net)
*/
public class JmxAgent {
private
EntityManager em;
private
Session session;
private
SessionFactory sf;
/**
*
Instantiate, register MBeans, enable Hibernate & Ehcache JMX
Statistics
*
@param emf javax.persistence.EntityManagerFactory to be passed in
*
from the invoking context (instead of creating it here
*
which is expensive operation)
*/
public
void init(EntityManagerFactory
emf)
throws Exception {
try {
// Create EntityManager from EntityManagerFactory passed in
// from the invoking context
em = emf.createEntityManager();
// Get Hibernate Session and SessionFactory from EntityManager
// *Important* for registering the Hibernate SessionFactory
// with org.hibernate.jmx.StatisticsService later on
// to enable JMX monitoring of Hibernate statistics
session = (Session)
em.getDelegate();
sf = session.getSessionFactory();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
em.close();
}
ObjectName on = new ObjectName
("Hibernate:type=statistics,application=SimpleJpaHibernateApp");
// 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(EntityManagerFactory emf)
throws Exception {
if(singleton == null) {
singleton = new JmxAgent();
singleton.init(emf);
}
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 4.2 Modify JSF Managed Beans to initiate JMX Agent
Unlike the HibernateTravelPOJO
application, there
is no HibernateUtil.java-like
object for getting Hibernate Session in
SimpleJpaHibernateApp. One solution is to initiate JmxAgent
during the 1st retrieval of EntityManager in following JSF
managed beans / controllers :
- simpleJpaHibernate.controllers.ProductController
- simpleJpaHibernate.controllers.ProductCodeController
- simpleJpaHibernate.controllers.ManufacturerController
e.g. as shown in Code Listing 4.2 for simpleJpaHibernate.controllers.ProductController
:
Code Listing 4.2 - ProductController.java
modified to initiate JmxAgent if needed
|
/*
*
ProductController.java
*
*/
package
simpleJpaHibernateApp.controller;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
....
import
simpleJpaHibernateApp.agents.JmxAgent;
import
simpleJpaHibernateApp.entities.Manufacturer;
import
simpleJpaHibernateApp.entities.Product;
import
simpleJpaHibernateApp.entities.ProductCode;
/**
* This version of ProductController uses JPA query with SQL joint
* to retrieve all Products associated with a given ProductCode
* indicated by its ID 'selectedProdCode'.
* This shows simple code modification to get additional behaviour.
*
* @author Max Poon (maxpoon@dev.java.net)
*/
public class
ProductController {
/**
Creates a new instance of ProductController */
public
ProductController() { }
private
Product product;
private
ProductCode selectedProductCode;
private
String selectedProdCode;
private
DataModel model;
@Resource
private
UserTransaction utx;
@PersistenceUnit(unitName = "SimpleJpaHibernateAppPU")
private
EntityManagerFactory emf;
private
EntityManager getEntityManager() {
initJMX();
return emf.createEntityManager();
}
//
Initiate JMX if needed
void initJMX() {
try {
JmxAgent.getDefault(emf);
} catch (Exception ex) {
ex.printStackTrace();
}
}
...
...
|
Similar modifications should also be
done for :
- simpleJpaHibernate.controllers.ProductCodeController
- simpleJpaHibernate.controllers.ManufacturerController
Then recompile SimpleJpaHibernateApp
with the above configurations and checked that it is working fine
getting also the web interface and functionalities as those 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".
Step 4.3 - Use
JConsole to Observe JMX Statistics
Similar to Step 2.3 in "Configuring
HibernateTutorialApp/HibernateTravelPOJO to enable JMX monitoring on
Hibernate and Ehcache", start JConsole
and connect to JVM running GlassFish (indicated by
"com.sun.enterprise.server.PELaunch"
in JConsole) and observe the
following real-time JMX information collected.
Starting with the "Listing ProductCodes" page :
Figure
4.3.1 - "Listing ProductCodes" page of SimpleJpaHibernateApp
|

Figure
4.3.2 - JConsole showing Hibernate Entity Names, Queries, 2nd Level
Cache Regions, and related statistics
|

Figure 4.3.3 -
JConsole showing Ehcache Statistics on ProductCode, with 6 cache miss
for the 6 ProductCode instances retrieved
|

Click on "SW" page on "Listing ProductCodes" page to get the following,
then click on "List of Product with this Product Code" to get the next
screen shown in Figure
4.3.7.
Figure 4.3.4 - "Detail of ProductCode" page
of SimpleJpaHibernateApp for ProdCode="SW"
|

Figure
4.3.5 - JConsole showing Hibernate Statistics being updated as compared
to Figure
4.3.2
|

Figure 4.3.6 -
JConsole showing Ehcache Statistics for ProductCode updated (with 2
more cache misses and 7 more cache hits) as compared to Figure
4.3.3
|

| Figure 4.3.7 - "Listing
Products" page of SimpleJpaHibernateApp for ProdCode="SW" |

| Figure
4.3.8 - JConsole showing Hibernate
Statistics being updated as compared to Figure
4.3.5 |

| Figure
4.3.9 - JConsole showing Ehcache
Statistics for ProductCode updated, with 1 more (ProductCode where
ProdCode="SW") cache hit as compared to Figure
4.3.6 |

Figure
4.3.10 - JConsole showing Ehcache
Statistics for Product, with 8 new retrieval, i.e. cache misses, for
the 8 Product
instances where ProdCode="SW" as shown in Figure
4.3.7
|

Step 4.4 - Modify ProductController to Enable Collection Cache
The SimpleJpaHibernateApp is extended 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" and the above steps, to demonstrate easy modification
to achieve JSF query views co-ordination and then JMX monitoring.
The ProductCode-to-Product entity 'navigation' and retrieval are done
by JPA Query with SQL joint and parameter binding as shown in Code
Listing
4.4.1, instead of one-to-many entity mapping and entity collection
retrieval. Hence, collection cache are not used as observed
previously from the
Hibernate JMX cache statistics on collection cache.
Coding Listing 4.4.1 -
simpleJpaHibernateApp.controllers.ProductController#getProducts() -
using JPA Query with SQL joint and parameter binding
|
/**
* This version of ProductController uses JPA query with SQL joint
* to retrieve all Products associated with a given ProductCode
* indicated by its ID 'selectedProdCode'.
* This shows simple code modification to get additional behaviour.
*
* @author Max Poon (maxpoon@dev.java.net)
*/
public class ProductController {
...
public
DataModel getProducts() {
EntityManager em = getEntityManager();
try{
Query q;
if (selectedProdCode != null
&& selectedProdCode.length() != 0) {
q = em.createQuery("select object(o)
from Product as o " +
"where o.productCode.prodCode = :selectedProdCode")
.setParameter("selectedProdCode", selectedProdCode);
} else {
q = em.createQuery("select object(o) from Product as o");
}
q.setMaxResults(batchSize);
q.setFirstResult(firstItem);
model = new ListDataModel(q.getResultList());
return model;
} finally {
em.close();
}
}
...
public int getItemCount() {
EntityManager em =
getEntityManager();
try{
Query q;
if (selectedProdCode != null &&
selectedProdCode.length() != 0) {
q = em.createQuery("select count(o)
from Product as o " +
"where o.productCode.prodCode = :selectedProdCode")
.setParameter("selectedProdCode", selectedProdCode);
}
else {
q = em.createQuery("select count(o) from Product as o");
}
int
count = ((Long) q.getSingleResult()).intValue();
return count;
} finally {
em.close();
}
}
...
|
An alternative to the above is to get the ProductCode
entity class using the selectedProdCode
string :
- ProductCode
productCode = em.find(ProductCode.class, selectedProdCode);
Then for ProductController.getProducts(),
retrieve all the associated Product's
from ProductCode.getProductonCollection()
using one-to-many association :
- productList
= (List<Product>) productCode.getProductCollection();
For ProductController.getItemCount(),
- count =
productCode.getProductCollection().size();
as shown in Code Listing 4.4.2 below :
Coding Listing 4.4.2 -
simpleJpaHibernateApp.controllers.ProductController#getProducts() and
getItemCount() -
using JPA Entity Collection, e.g. to show use of Hibernate Collection
Cache in additional to Class Caching
|
/**
* This version of ProductController uses entity collection for
* retrieving all Products associated with a given ProductCode
* indicated by its ID 'selectedProdCode' to show JMX monitoring
* on collection cache in additional to entity class cache
*
* @author Max Poon (maxpoon@dev.java.net)
*/
public class ProductController {
...
public DataModel getProducts() {
EntityManager em = getEntityManager();
try{
List<Product> productList;
if (selectedProdCode != null && selectedProdCode.length() != 0)
{
ProductCode productCode = em.find(ProductCode.class, selectedProdCode);
productList = (List<Product>) productCode.getProductCollection();
} else {
Query q =
em.createQuery("select object(o) from Product as o");
q.setMaxResults(batchSize);
q.setFirstResult(firstItem);
productList = (List<Product>) q.getResultList();
}
model = new ListDataModel(productList);
return model;
}
finally {
em.close();
}
}
...
public int getItemCount() {
EntityManager em = getEntityManager();
try{
int count;
if (selectedProdCode != null &&
selectedProdCode.length() != 0) {
ProductCode productCode = em.find(ProductCode.class, selectedProdCode);
count = productCode.getProductCollection().size();
} else {
Query q =
em.createQuery("select count(o) from Product as o");
count = ((Long)
q.getSingleResult()).intValue();
}
return count;
} finally {
em.close();
}
...
|
The entity class ProductCode.java
is also required to further enable collection cache on ProductCode.productCollection
(similarly for Manufacturer.productCollection
in Manufacturer.java) :
Code Listing 4.4.3 - ProductCode.java with
Hibernate @Cache Annotation to enable Entity Class Cache on ProductCode
and Collection Cache on ProductCode.productionCollection
|
/*
* ProductCode.java
*
*/
package
simpleJpaHibernateApp.entities;
import java.io.Serializable;
import java.util.Collection;
import
javax.persistence.CascadeType;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import javax.persistence.Id;
import
javax.persistence.NamedQueries;
import
javax.persistence.NamedQuery;
import
javax.persistence.OneToMany;
import
javax.persistence.Table;
import
org.hibernate.annotations.Cache;
import
org.hibernate.annotations.CacheConcurrencyStrategy;
/**
* Entity class
ProductCode, adding Hibernate Annotations to enable
* Entity Class Cache on ProductCode, and
* Collection Cache on ProductCode.productCollection
*
* @author Max Poon
(maxpoon@dev.java.net)
*/
@Entity
@Table(name =
"PRODUCT_CODE")
@NamedQueries( {
......
} )
@Cache(usage =
CacheConcurrencyStrategy.READ_WRITE)
public class ProductCode implements Serializable {
@Id
@Column(name = "PROD_CODE", nullable = false)
private
String prodCode;
@Column(name = "DISCOUNT_CODE", nullable = false)
private
char discountCode;
@Column(name = "DESCRIPTION")
private
String description;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "productCode")
@Cache(usage =
CacheConcurrencyStrategy.READ_WRITE)
private
Collection<Product> productCollection;
......
|
After recompiling SimpleJpaHibernateApp and invoking its "Listing
Products" page for ProdCode="SW"
( Figure
4.3.7), the
JMX statistics collected by JConsole are shown :
* Hibernate JMX statistics in Figure
4.4.1
* Ehcache JMX statistics
- Class Cache for simpleJpaHibernateApp.entities.ProductCode,
in Figure
4.4.2
- Class Cache for simpleJpaHibernateApp.entities.Product,
in Figure
4.4.3
- Collection Cache simpleJpaHibernateApp.entities.ProductCode.productionCollection,
in Figure
4.4.4
Figure
4.4.1 - JConsole showing Hibernate JMX statistics, on
SimpleJpaHibernateApp using @Cache Annotation (to enable Collection
Cache), as compared to Figure
4.3.8
for SimpleJpaHibernateApp using JPA Query
|
| Figure
4.4.2 - JConsole showing Ehcache JMX Class Cache Statistics for
ProductCode, on SimpleJpaHibernateApp using @Cache
Annotation to enable Collection Cache, as compared to Figure
4.3.9 for
SimpleJpaHibernateApp using JPA Query |
| Figure
4.4.3 - JConsole showing Ehcache JMX Class Cache Statistics for
Product, on SimpleJpaHibernateApp using @Cache
Annotation to enable Collection Cache, as compared to Figure
4.3.10 for
SimpleJpaHibernateApp using JPA Query |
| Figure
4.4.4 - JConsole showing Ehcache JMX Collection Cache Statistics for
ProductCode.productCollection, on SimpleJpaHibernateApp using @Cache
Annotation to enable Collection Cache (Collection Cache not used in
SimpleJpaHibernateApp using JPA Query) |
Resulting from the above JMX statistics collected on Hibernate and
Ehcache, an indicative comparison of cache and query statistics for the
same use case can be tabulated, e.g. for the mentioned case of querying
all the 6 Product's
associated with ProductCode
where ProdCode="SW",
showing the following major observations :
- Querying using entity collection causes slightly more entity
loading (28 vs 29) but, at the same time, more utilisation of entity
class cache and Hibernate 2nd level cache
- (2ndLevelCacheHit
of 2 vs 109, for the respective cases)
- Querying using entity collection improves query by :
- requiring more simple query (compare the different QueryExecutionMaxTimeQueryString's)
- reducing time of the longest query execution (QueryExecutionMaxTime from 181
ms to 60 ms)
- reducing number of queries required (QueryExecutionCount from 27 to
20)
|
Using
JPA Query
with SQL Joint
|
Using
Entity Collection
& Collection Cache
|
Hibernate JMX Statistics
|
|
|
Entity
Load Count
|
28
|
29
|
2nd
Level Cache Hit
|
2
|
109
|
2nd
Level Cache Miss
|
1
|
2
|
2nd
Level Cache Put
|
28
|
30
|
Query
Execution Count
|
27
|
20
|
Query
Execution Max Time (ms)
|
181
|
60
|
Query
Execution Max Time Query String
|
select count(o)
from Product as o where o.productCode.prodCode
= :selectProdCode;
|
select object(o)
from Product as o;
|
Ehcache JMX Statistics
|
|
|
| ProductCode
Cache Hit / Miss |
3 / 13
|
8 / 16
|
Product
Cache Hit / Miss
|
0 / 8
|
48 / 8
|
ProductCode.productCollection
Cache Hit / Miss
|
Not Available
|
6 / 2
|
Notes:
- Relative values of QueryExecutionMaxTime
may differ slightly in different testing
environments and value above are just the results collected during my
testings.
- The new structure of the SimpleJpaHibernateApp application shown
as NetBeans Projects is included for reference :
Figure 4.4.5 - New Structure of
SimpleJpaHibernateApp NetBeans Project
|

|
Summary
To summarise, the above shows :
- ways of extending JSF-Hibernate applications to enable JMX
monitoring on its Java object/relational persistence (Hibernate v3) and
cache (Ehcache 1.3.0) implementations, for both Hibernate v3 and
JPA-with-Hibernate applications
- an example (using SimpleJpaHibernateApp) of how JMX statistics
enable comparison of query execution and cache utilisation for
application providing same functionalities but using different
implementation strategies
Note: While only JMX statistics
for Java object/relational persistence (Hibernate v3) and cache
(Ehcache 1.3.0) implementations are discussed above,
application-specific JMX statistics can also be gathered by building
custom JMX MBeans, e.g. as shown in the NetBeans tutorial " Getting
Started with JMX Monitoring in NetBeans IDE 5.0".
Acknowledgements
Special thanks to Greg Luck
for his collaboration in the configuration of HibernateTravelPOJO and
SimpleJpaHibernateApp to enable JMX monitoring on Ehcache 1.3.0
released
earlier in June 11, 2007.
Resources
Note: All the 3 application
source packages can either be opened and compiled in NetBeans 5.5 or above, or
compiled by Ant 1.6.5 or above.
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
|