CARVIEW |
![]() Get Involved
Get Informed
Get Connected
Search
Online Books:
|
![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
Max Poon's Blog
Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 4 - Switching from Hibernate JPA to Glassfish JPA/TopLink Essentials (with Optional NetBeans Project Resources and Source Package Path Names Renaming)Posted by maxpoon on August 11, 2007 at 09:29 AM | Permalink | Comments (0)BackgroundIt was shown in the previous articlehow to configure Java Persistence API (JPA) based application to use Hibernate and Ehcache as the JPA and caching implementation provider respectively. SimpleJpaHibernateApp is developed based on JSR 220 Java Persistence API with optional Hibernate-specific options, e.g. in persistence.xml or @Cache Annotations for caching applied. Hence, due to the pluggability of the Java Persistence API architecture, JPA-compliant applications such as SimpleJpaHibernateApp can easily be switched to make use of other Java Persistence providers such as Glassfish JPA. This article describes how this can be done. Glassfish JPA / TopLink EssentialsAs mentioned in Oracle's TopLink JPA web page, "TopLink Essentials is the open-source community edition of Oracle's TopLink product. It provides the JPA functionality for the EJB 3.0 Reference Implementation.".As also mentioned in Glassfish Java Persistence API Implementation web page, TopLink Essentials is "the Java Persistence API implementation at the GlassFish community", and adopted as the JPA Reference Implementation within Glassfish Java EE Reference Implementation. Configuring SimpleJpaHibernateApp to use Glassfish JPA
The
configuration works involve the following suggested steps : |
Figure 1B - Renaming
"SimpleJpaHibernateApp" to "SimpleJpaToplinkApp" in NetBeans IDE |

This changes the NetBeans project name in ...../SimpleJpaToplinkApp/nbproject/project.xml to SimpleJpaToplinkApp as shown below.
Code Listing 1B - New project
name in nbproject/project.xml (changes in red) |
<?xml version="1.0"
encoding="UTF-8"?> <project xmlns="https://www.netbeans.org/ns/project/1"> <type>org.netbeans.modules.web.project</type> <configuration> <data xmlns="https://www.netbeans.org/ns/web-project/3"> <name>SimpleJpaToplinkApp</name> .... </data> </configuration> </project> |
(1C) Change the Persistence Unit name from "SimpleJpaHibernateAppPU" to "SimpleJpaToplinkAppPU" in persistence.xml
Code Listing 1C - Changing Persistence-Unit name from "SimpleJpaHibernateAppPU" to "SimpleJpaToplinkAppPU" in persistence.xml |
<?xml version="1.0"
encoding="UTF-8"?> <persistence version="1.0" xmlns="https://java.sun.com/xml/ns/persistence" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="SimpleJpaToplinkAppPU" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/sample</jta-data-source> .... </persistence-unit> </persistence> |
[Note: Steps (2A) and (2B) below involve also changes in persistence.xml and hence may be done here as well, but are left to be done later as they are necessary steps to be grouped in Step 2.]
(1D) Re-open the "renamed SimpleJpaToplinkApp" project in NetBeans IDE, then change the Java package path name "SimpleJpaHibernateApp" to "SimpleJpaToplinkApp" by right-clicking on the concerned Source Packages and selecting [Refactor] > [Rename...] to change the package names from :
- SimpleJpaHibernateApp.agents to SimpleJpaToplinkApp.agents
- SimpleJpaHibernateApp.controller to SimpleJpaToplinkApp.controller
- SimpleJpaHibernateApp.entities to SimpleJpaToplinkApp.entities
Figure 1D - Using NetBeans IDE "Refactor"
to Rename Java Source Packages path names |

Step 2 - Changing Java Persistence Provider in Persistence-Unit
(2A) Double click on [persistence.xml] under [Configuration Files] in [Projects] Window to open up the [Persistence Units] Design Panel, then change the Persistence Provider for SimpleJpaToplinkAppPU from "Hibernate" to "TopLink(default)" as follows.Figure 2A - Using Netbeans IDE Design Panel for persistence.xml to Change Java
Persistence Provider |

(2B) Switch from "Design" to "XML" Panel for persistence.xml, observe the change of <provider> element, replace the Hibernate caching properties with TopLink caching, and select [File] > [Save] to save the modified persistence.xml as shown :
Code Listing 2B - Changing <provider>
and <properties> for caching in persistence.xml |
<?xml version="1.0"
encoding="UTF-8"?> <persistence version="1.0" xmlns="https://java.sun.com/xml/ns/persistence" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="SimpleJpaToplinkAppPU" transaction-type="JTA"> <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider </provider> <jta-data-source>jdbc/sample</jta-data-source> <class>simpleJpaToplinkApp.entities.Manufacturer</class> <class>simpleJpaToplinkApp.entities.ProductCode</class> <class>simpleJpaToplinkApp.entities.Product</class> <properties> <property name="toplink.cache.type.Manufacturer" value="HardWeak"/> <property name="toplink.cache.type.ProductCode" value="Full"/> <property name="toplink.cache.type.Product" value="SoftWeak"/> </properties> </persistence-unit> </persistence> |
While this configuration (similar to corresponding ones for Hibernate) in persistence.xml will enable basic caching for specified JPA entity classes, configuration for Glassfish JPA is a bit simplier (and also more "restrictive") as Glassfish JPA has already included and can only uses its own caching implementation instead of requiring/having the choice to specify/configure for an external caching implementation such as Ehcache.
Any @Cache annotations used in entity class to Hibernate caching should be removed as they are not supported by Glassfish JPA / TopLink Essentials (though TopLink may have its own @Cache annotations). Use <properties> configuration in persistence.xml to enable caching in Glassfish JPA.
Refer to Further Resources for more information on Glassfish JPA / TopLink Essentials caching architecture and options such as "Full", "HardWeak", and "SoftWeak".
(2C) Change SimpleJpaToplinkApp's referencing Library from Hibernate libraries to TopLink Essentials library.
Figure 2C - SimpleJpaToplinkApp changed to
use TopLink Essentials library in NetBeans IDE |

(2D) Since JMX monitoring is not currently used in SimpleJpaToplinkApp, from all 3 controllers (ManufacturerController, ProductCodeController, ProductController), comment out statements :
- import simpleJpaToplinkApp.agents.JmxAgent;
- initJMX();
- void initJMX() { ... }
- @PersistenceUnit(unitName = "SimpleJpaHibernateAppPU")
- @PersistenceUnit(unitName = "SimpleJpaToplinkAppPU")
Step 3 -
(Optional) Changing DB Schema Name to APP_SimpleJpaToplinkApp, and
Fixing the Web App Context Path and Referencing URIs
(3A) For naming consistency, change the DB schema name to from
"APP_SimpleHibernateApp" to "APP_SimpleJpaToplinkApp" using NetBeans
IDE "Rename" function.Figure 3A1 - Using NetBeans IDE "Rename" to
Change DB Schema Name |

Figure 3A2 - Using NetBeans IDE "Rename" to
Change DB Schema Name |

(3B) Also, the web application context path can optionally be fixed to "SimpleToplinkApp" (as below), and subsequently all JSF views referencing previous context URI and text labels "SimpleHibernateApp" are required to be changed to "SimpleToplinkApp".
Figure 3B - Changing Context Path |

Step 4 - Compiling and
Deploying the new "SimpleJpaToplinkApp"
Finally, the "new" SimpleJpaToplinkApp project should look as shown in
Figure 3B, and
is ready to be compiled and deployed. The service will be
available at deployed Glassfish HTTP service port with context URI "/SimpleJpaToplinkApp" as
specified above.Further Resources
- Oracle: TopLink JPA
- Glassfish Java Persistence API Implementation web page
- Oracle: Overview of TopLink Caching and Locking
- Oracle TopLink Developer's Guide - Understanding the Cache
- Wonseok
Kim's Blog - Understanding the cache of TopLink Essentials(GlassFish
JPA)
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 | PermalinkBackground
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, created with the NetBeans tutorial "Using Hibernate With the Java Persistence API", 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="https://java.sun.com/xml/ns/persistence" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://java.sun.com/xml/ns/persistence https://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" "https://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="https://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 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();
- SessionFactory sessionFactory = session.getSessionFactory();
(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.
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
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 |
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 | PermalinkBackground
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
- using the sample application ('HibernateTutorialApp') created with the NetBeans tutorials "Using Hibernate With the NetBeans Visual Web Pack" (previously as "Using Hibernate With the Sun Java Studio Creator IDE")
- JPA-with-Hibernate applications
- using the sample application ('SimpleJpaHibernateApp') created with the NetBeans tutorial "Using Hibernate With the Java Persistence API"
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 :
- 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
Software Requirements
- Deployment on J2EE 1.4 or above compliant application server (e.g. Sun Java System Application Server 8.2, GlassFish v1, or above) running Sun JDK 5 or above (Sun JDK 6 suggested) is required for HibernateTutorialApp/HibernateTravelPOJO to have JMX monitoring.
- Deployment on Java EE 5 compliant application server (e.g. GlassFish v1 or above) running Sun JDK 5 or above (Sun JDK 6 suggested) is required for SimpleJpaHibernateApp to have JMX monitoring.
- The steps below assume use of NetBeans 5.5 / 5.5.1, GlassFish v1, and on Sun JDK 6 or above to allow JMX Dynamic Attach from JConsole to the Sun JDK 6 JVM running GlassFish for JMX monitoring.
(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
- hibernatetravelpojo/Person.hbm.xml
- hibernatetravelpojo/Trip.hbm.xml
Also, the following Ehcache configuration file ehcache.cfg.xml is required in the root of Java source directory together with hibernate.cfg.xml.
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.
- org.hibernate.jmx.StatisticService , which
- implements org.hibernate.jmx.StatisticServiceMBean , and hence
- extends org.hibernate.stat.Statistics
- StatisticService.setSessionFactory(SessionFactory
sf);
StatisticService.setStatisticsEnabled(true);
MBeanServer.registerMBean(StatisticService statMBean, ObjectName objectName);
In case of Ehcache, four types of 'pre-fabricated' MBeans have already been provided, including :
- CacheManager MBean
- Cache MBean
- CacheConfiguration MBeans
- CacheStatistics MBeans
- ManagementService.registerMBeans(CacheManager, MBeanServer, registerCacheManger, registerCache, registerCacheConfiguration, registerCacheStatistics);
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.
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 https://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 https://localhost:port/HibernateTutorialApp in browser, or
- right-click on the [HibernateTutorialApp] project in NetBeans IDE and select [Run Project]
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
=> 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
- as the loaded entities and collection are put into the respective caches
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.
- entity statistics via Code Listing 2.3.2a
- 2nd level cache statistics via Code Listing 2.3.2b
- 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()
"Introduction to the Spring Framework in NetBeans IDE" Tutorial by Troy Giunipero and Craig MacKay
Posted by maxpoon on June 15, 2007 at 11:32 PM | PermalinkIf you are a Spring Framework developer, you will find the Spring Framework Module for NetBeans useful as it provides :
- Framework Support (enables the Spring Framework as an option when creating a new web application)
- Spring XML Catalog (provides Spring related XSD and DTD's to enable XML code completion)
- Integrated Library Management (installs libraries required for the Spring Framework, as well as additional required libraries)
Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 1 - Co-ordinating Query Views Based on Parameter Passing from JSF View to Managed Bean
Posted by maxpoon on June 13, 2007 at 12:47 PM | PermalinkBackground
The NetBeans tutorial "Using
Hibernate With the Java Persistence API" nicely demonstrates, by
using the
NetBeans IDE, easy construction of :- Java Persistence API (JPA) entity classes from given database
schema (using NetBeans IDE bundled 'sample' database)
- JavaServer Faces (JSF) CRUD application (on the 'sample'
database) using
JPA and entity classes generated above
- addition of data validation using JPA
Annotations and Hibernate
Validator framework
- retrieval of Hibernate
Session from JPA
EntityManager to enable usage of Hibernate
Criteria
API and Query-By-Example
As the resulting created application provides individual CRUD functions to the actually mutually-associated entity classes, it makes sense to see how, using JSF, we can, easily in the two steps described, extend the application to add new web query views from the CRUD view of one entity class to list the links to CRUD views of its associated entity classes with re-use of existing individual CRUD views as much as possible. This is an example of co-ordinating query views based on parameter passing from JSF View to Managed Bean. Adding a 'new view' to list all Products associated with a selected ProductCode via the ProductCode-Product one-to-many association is used here.
Extending The Sample Application
Based on the "Using Hibernate With the Java Persistence API" tutorial (but choosing the sample database tables ProductCode, Product, and Manufacturer instead of Customer and DiscountCode), our JSF-JPA-Hibernate sample application (let's call it 'SimpleJpaHibernateApp') can be created. (Please refer to the original tutorial for other details of software needed and environment set-up). Figure 1 - 'Sample' Database Tables to be
used by SimpleJpaHibernateApp |
![]() |
At this time, our SimpleJpaHibernateApp created provides individual CRUD functions to the three actually associated entity classes (e.g. both ProductCode-Product and Manufacturer-Product having one-to-many associations).
Here, we shall pick the ProductCode->Product navigation (i.e. enquiring on all Products for CRUD, given a selected ProductCode) since there are 6 ProductCodes and 30 Products (so it's in average 1:5 ratio) from the out-of-the-box NetBeans 'sample' database.
In this case, our application (and the targeted new query function) should be as follows, starting with its home page with the HTML links to :
- "List of ProductCode" -
listing all the ProductCodes
records (in the 'sample' database)
- "List of Product" - listing all the Products records
- "List of Manufacturer" - listing all the Manufacturer records
Figure 2 - SimpleJpaHibernateApp Home Page |

Let's start the query navigation with ProductCode by clicking on the "List of ProductCode" link to lists all the ProductCodes :
Figure 3 - "Listing ProductCodes" Page |

Then, click on one of the ProductCodes, e.g. "SW" in ProdCode column, the "Detail of ProdCode" for ProdCode "SW" will be displayed :
Figure 4 - "Detail of ProductCode" Page |

Now, it would be nice if we can add a HTML link "List of Product with this ProductCode" (highlight in red box) to display all the Products of this selected ProductCode with ProdCode="SW" :
Figure 5 - New (Desired) "Detail of ProductCode" Page |

So that clicking on "List of Product with this ProductCode" will display :
Figure 6 - New (Desired) "Listing Products"
Page |

This can be done easily in JSF
An quite obvious way is to get the selected ProdCode in the "Detail of ProductCode" page, stored in JSF EL :- #{productCode.productCode.prodCode}
- <h:commandLink action="productCode_list" value="Show All ProductCode"/>
Code Listing 1 - Original "Detail of
ProductCode" Page - Location: simpleJpaHibernateApp/web/productCode/Detail.jsp |
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib uri="https://java.sun.com/jsf/core" prefix="f" %> <%@taglib uri="https://java.sun.com/jsf/html" prefix="h" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>SimpleJpaHibernateApp - Detail of ProductCode</title> </head> <body> <f:view> <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/> <h1>Detail of productCode</h1> <h:form> <h:panelGrid columns="2"> <h:outputText value="ProdCode:"/> <h:outputText title="ProdCode" value="#{productCode.productCode.prodCode}"/> <h:outputText value="DiscountCode:"/> <h:outputText title="DiscountCode" value="#{productCode.productCode.discountCode}"/> <h:outputText value="Description:"/> <h:outputText title="Description" value="#{productCode.productCode.description}"/> </h:panelGrid> <h:commandLink action="productCode_edit" value="Edit" /> <br> <h:commandLink action="productCode_list" value="Show All ProductCode"/> <br> <a href="/SimpleJpaHibernateApp/index.jsp">Back to Home Page</a> </h:form> </f:view> </body> </html> |
Now, let's look at how the subsequent "List of Product" works :
Code Listing 2 - "List of Product" Page - Location: simpleJpaHibernateApp/web/product/List.jsp |
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib uri="https://java.sun.com/jsf/core" prefix="f" %> <%@taglib uri="https://java.sun.com/jsf/html" prefix="h" %> <html> ... <body> <f:view> <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/> <h1>Listing Products</h1> <h:form> <h:commandLink action="#{product.createSetup}" value="New Product"/> <br> <a href="/SimpleJpaHibernateApp/index.jsp">Back to Home Page</a> <br> <h:outputText value= "Item #{product.firstItem + 1}..#{product.lastItem} of #{product.itemCount}"/> <h:commandLink action="#{product.prev}" value="Previous #{product.batchSize}" rendered="#{product.firstItem >= product.batchSize}"/> <h:commandLink action="#{product.next}" value="Next #{product.batchSize}" rendered="#{product.lastItem + product.batchSize <= product.itemCount}"/> <h:commandLink action="#{product.next}" value="Remaining #{product.itemCount - product.lastItem}" rendered="#{product.lastItem < product.itemCount && product.lastItem + product.batchSize > product.itemCount}"/> <h:dataTable value='#{product.products}' var='item' border="1" cellpadding="2" cellspacing="0"> ... </h:dataTable> </h:form> </f:view> </body> </html> |
It can be observed that Products and ItemCount are retrieved from the JSF Expressions :
- #{product.products} which binds to the getProduct() method
- #{product.itemCount} which binds to the getItemCount() method
[Note: Examing ProductController.java shows that the other #{product.firstItem} and #{product.lastItem} actually derive from #{product.itemCount}.]
Hence, if we can have these two methods be aware of the selected ProdCode to :
- get only Products with the selected Prodcode
- count only Products with the selected ProdCode
Step 1 - Add New JSF CommandLink
in "Detail of ProducCode" Page to Pass the Selected ProdCode to New
Bean Method in ProductController
Using the added <h:commandLink
...> (highlighted below), the selected ProdCode in #{productCode.productCode.prodCode}
can be passed as JSF FacesContext
parameter selectedProdCode
from simpleJpaHibernateApp/web/productCode/Detail.jsp
to simpleJpaHibernate.controller.ProductController
:Code Listing 3 - New
<h:commandLink...> added to "Detail of ProductCode" page - simpleJpaHibernateApp/web/productCode/Detail.jsp |
.... <h:commandLink action="productCode_list" value="Show All ProductCode"/> <br> <h:commandLink action="#{product.setSelectedProdCodeDisplayProducts}" value="List of Product with this ProductCode"> <f:param name="selectedProdCode" value="#{productCode.productCode.prodCode}"/> </h:commandLink> <br> <a href="/SimpleJpaHibernateApp/index.jsp">Back to Home Page</a> .... |
Step 2 - Add New Bean Property and Method, and Modify Related Bean Methods in ProductController
The 'passed-in' FacesContext selectedProdCode parameter is to be retreived by ProductController with the following new method setSelectedProdCodeDisplayProducts()Code Listing 4 - New bean methods
setSelectedProdCode(String selectedProdCode) and setSelectedProdCodeDisplayProducts() of simpleJpaHibernateApp.controller.ProductController |
/** * Setter for selectedProdCode property * @param selectedProdCode String PROD_CODE column value of the selected * ProducCode e.g. in productCode/Detail.jsp */ public void setSelectedProdCode(String selectedProdCode) { this.selectedProdCode = selectedProdCode; } /** * setSelectedProdCodeDisplayProducts() : * <ol> * <li>Get 'selectedProdCode' parameter from FacesContext</li> * <li>Set bean property 'selectedProdCode' with the parameter value</li> * <li>Return "product_list" to invoke product/List.jsp as defined in * faces-config.xml to display Products with this selectedProdCode</li> * </ol> */ public String setSelectedProdCodeDisplayProducts() { String _selectedProdCode = (String) FacesContext.getCurrentInstance() .getExternalContext().getRequestParameterMap() .get("selectedProdCode"); setSelectedProdCode(_selectedProdCode); return "product_list"; } |
Also, the getProducts() and getItemCount() methods are required to be modified to get the 'selectedProdCode-aware' query behaviour :
Code Listing 5 - Modified managed bean
methods getProducts() and getItemCount() of
simpleJpaHibernateApp.controller.ProductController |
/** * Retrieve Products and return as ListDataModel according to: * <ol> * <li>ProductCode selected already * <code> * (selectedProdCode != null && selectedProdCode.length() != 0) * </code> * => retrieve Products with the selected ProductCode * </li> * <li>ProductCode not selected (otherwise) * => retrieve all Products * </li> * </ol> */ 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(); } } /** * Count no. of Products items according to: * <ol> * <li>ProductCode selected already * <code> * (selectedProdCode != null && selectedProdCode.length() != 0) * </code> * => count number of Products with the selected ProductCode * </li> * <li>ProductCode not selected (otherwise) * => count number of all Products * </li> * </ol> */ 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(); } } |
Some Final Steps - Related to index.jsp
Basically, the addition of new query based on the selected ProdCode (as
criteria) passed from previous "Detail
of ProductCode" JSF page / view (based also on
modification/re-use of existing "Listing
Products" view) is completed.However, also due to the introduction of new query behaviour to the "Listing of Products" view, there are a few subsequent amendments to the application needed.
This includes the requirement to reset the newly introduced bean property selectedProdCode of ProductController in case of invocation from the application home page, to display all available Products in the database as expected. Again, this can be done by the very same JSF CommandLink, this time with "" for the selectProdCode parameter :
- <h:commandLink
value="List of Product"
action="#{product.setSelectedProdCodeDisplayProducts}">
<f:param name="selectedProdCode" value=""/>
</h:commandLink>
Code Listing 6 - Modified index.jsp |
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib uri="https://java.sun.com/jsf/core" prefix="f" %> <%@taglib uri="https://java.sun.com/jsf/html" prefix="h" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> <%-- index.jsp - Modified from index.jsp_orig to use JSF <h:commandLink ...> to clear any previously set ProductController#selectedProdCode for listing Products via 'product_list' action @author Max Poon (maxpoon@dev.java.net) --%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Simple JPA Hibernate Application</title> </head> <body> <f:view> <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/> <h1>Simple JPA Hibernate Application</h1> <h:form> <br/> <h:commandLink value="List of ProductCode" action="productCode_list"/> <br/> <h:commandLink value="List of Product" action="#{product.setSelectedProdCodeDisplayProducts}"> <f:param name="selectedProdCode" value=""/> </h:commandLink> <br/> <h:commandLink value="List of Manufacturer" action="manufacturer_list"/> </h:form> </f:view> </body> </html> |
This requires configuration / invocation of the new index.jsp as JSF View via the application's web.xml servlet-mapping :
Code Listing 7 - Example new
servlet-mapping required in
web.xml |
.... <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> .... |
with all correspondingly links to the SimpleJpaHibernateApp home page modified from index.jsp to index.jsf, i.e. :
Code Listing 8 - Modified href link to
"Home Page" in all referencing JSP's |
.... <%-- Modified link from /SimpleJpaHibernateApp/index.jsp to /SimpleJpaHibernateApp/index.jsf --%> <a href="/SimpleJpaHibernateApp/index.jsf">Back to Home Page</a> .... |
For completeness' sake in this case, we should also have an index.html (suggested to be set as welcome-file in web.xml) so that requesting :
- https://host:port/simpleJpaHibernateApp/
- https://host:port/simpleJpaHibernateApp/index.jsf.
Done, Ready for Compilation, Deployment and Testing
So, SimpleJpaHibernateApp is now ready for compilation, deployment and testing, e.g. by clicking "List Product with this ProductCode" from "Detail of ProductCode" page with ProductCode as, e.g. "HW", and you should get :Figure 6 - "Listing Products" Page for "HW"
ProductCode |

while clicking "List of Product" on the Home Page, you should get all the available Products for ProdCode "SW", "HW", etc.
Figure 7 - "Listing Products" Page for All
ProductCodes, i.e. All Available Products |

If you can get the above query views working, congratulations! Your SimpleJpaHibernate should be working fine, and ready for your further exploration!
Coming Next
In coming (hopefully soon) "Extending the NetBeans Tutorial JSF-JPA-Hibernate Application, Part 2", I would like to share on enabling JMX monitoring on Hibernate 3.2.x, and on the latest Ehcache 1.3.0 with full JMX support and detail per-cache monitoring statistics (yes, it's great!) - using our SimpleJpaHibernateApp as example (thanks to Ehcache's creator and maintainer Greg Luck for his helping me get the JMX monitoring on Ehcache working for the SimpleJpaHibernateApp, when we met at JavaOne May this year)Stay tuned!


August 2007
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Search this blog:
Categories
Community: Java EnterpriseCommunity: NetBeans
J2EE
JavaOne
Performance
Archives
August 2007
June 2007
May 2007
Recent Entries

![]()
|