EclipseLink is an open-source persistency framework for mapping Java objects to relational data and vice versa which is called Object-Relational Mapping (ORM). Besides implementing the Java Persistence API (JPA) standard, it also provides capabilities for Object-XML Mapping (OXM) and the creation of Database Web Services.
The JPA standard specifies caching functionality. Caching improves performance since data that is already queried and present in the cache can be fetched from memory instead of executing all queries in the backend database. However, this means that data should also be modified through the same cache managed by the JPA provider. If not, the cache won't be aware of changes and becomes out-of-synch with the actual data stored in the backend. This results in incorrect data being returned to the clients of the EclipseLink-based application. A typical situation in which this occurs is when IT operations directly changes data in the database on behalf of users or when solving issues and thereby bypassing the cache.
There are a few approaches to deal with such situations:
- Restart the application server or application after the change to clear the cache;
- Disable caching in the application altogether;
- Expand the application (user interface, persistency layer) so that IT operations has dedicated functionality to modify data through the application instead of being forced to modify data in the backend database;
- Implement a mechanism to automatically invalidate the EclipseLink cache triggered by events from the database;
- Configure the persistency layer so that entities in the cache are automatically invalidated on a regular interval making sure that data can only be incorrect or incomplete for a certain time-period.
This blog describes a way to manage EclipseLink caches that we use at customer projects to help IT operations and application managers and doesn't have the disadvantages named earlier. It uses:
- the out-of-the-box support by EclipseLink for Java Management Extensions (JMX);
- the MBeans provided by WebLogic Server;
- the monitoring application JConsole that is JMX-compliant and shipped with the Java Development Kit (JDK).
One-time configuration of WebLogic to enable remote JMX connectionsWeblogic Server needs to be configured to allow for remote JMX connections that are set up from JConsole and to enable the invocation of MBeans. The following blogs show you how to accomplish this:
Some pointers here:
- Make sure you add the Java options eclipselink.register.dev.mbean=true and eclipselink.register.run.mbean=true to the start script of the WebLogic Server on which the EclipseLink applications run. Adding these parameters makes sure that the EclipseLink MBeans show up in JConsole.
- Restart the WebLogic Server after the configuration changes.
Using JConsoleAfter configuring and restarting WebLogic Server, the default WebLogic server logfile should include the endpoints for the JMX servers to which we connect using JConsole. For example:
<JMX Connector Server started at service:jmx:iiop://localhost:7001/jndi/weblogic.management.mbeanservers.runtime .>
<JMX Connector Server started at service:jmx:iiop://localhost:7001/jndi/weblogic.management.mbeanservers.edit .>
<JMX Connector Server started at service:jmx:iiop://localhost:7001/jndi/weblogic.management.mbeanservers.domainruntime .>
After setting the JAVA_HOME and WEBLOGIC_HOME environment variables as indicated in the blogs, you can now start JConsole using the command line:
jconsole -J-Djava.class.path=%JAVA_HOME%\lib\jconsole.jar;%JAVA_HOME%\lib\tools.jar;%WL_HOME%\server\lib\wljmxclient.jar -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -J-Dcom.sun.management.jmxremote
Enter the credentials you provided in WebLogic Server for the IIOP protocol and enter the JMX endpoint for the mbeanservers.runtime to connect to WebLogi Server. JConsole now lets you inspect and manage all sorts of aspects such as memory, threads, classes, and so on.
To view the currently active EclipseLink sessions click on the "MBeans" tab and expand the node "TopLink". Every active EclipseLink session is shown as separate subnode. Expand a session and select "Attributes" to inspect the EclipseLink session. Clicking on the "NumberOfObjectsInAllIdentityMaps" shows a graph displaying the number of cached entities.
You can now clear the cache of an EclipseLink session at runtime by executing the operation "invalidateAllIdentityMaps" on the "Operations" page. This operation can be used to clear the cache after someone, e.g. IT operations, modifies the backend data directly and bypasses the EclipseLink persistency layer.
Note (thanks to Shaun Smith): You should be calling invalidateAllIdentityMaps() which has replaced initializeAllIdentityMaps(). Invalidation ensures that object identity is not lost in a running transaction. Initialization does not and should only be used safely in single threaded dev/test.
By using this approach, IT operations and application managers can do their job that includes direct data modifications to solve urgent issues and user requests, and be able to refresh the EclipseLink cache without downtime and impact for end users.