Recently, I was asked by a client to investigate how they might configure a Liferay Portal version 6 instance to completely eliminate caching of a few specific entities; in particular, the User and Group entities.   On the surface, this sounds like a relatively simple task; however, the way that Liferay handles caching makes things a bit more complicated if your goal is to disable ALL caching for a particular type of entity.

Liferay stores information for entities such as Users in three separate caches; the entity cache, the finder cache, and the Hibernate cache.  The entity and finder caches are maps maintained internally by Liferay, intended to speed up access for instances of a portal implementation object, while the Hibernate cache is maintained by the Hibernate cache provider, and is configured and maintained independently of the two Liferay caches.  The entity cache is essentially a basic map associating the value object for the entity with it’s database primary key.  The finder cache is a bit more complex; storing paths to value objects and lists of value objects; the path is treated as the key, and the primary key for the value object is stored as the map value.  The Hibernate cache is a standard cache for the Hibernate ORM framework; the details of what Hibernate does with this cache are beyond the scope of this article, but I will note that LIferay by default uses Ehcache as its Hibernate cache provider.

Disabling caching for a specific Liferay model object thus requires three changes to be made; the first change disables storage for that object in the entity cache, the second change disables storage in the finder cache, and the third change disables storage in the Hibernate cache.  The first two changes are extremely straightforward; you merely add the following lines to portal-ext.properties (I will be using the User entity for these examples):

# Disable entity caching for User
value.object.entity.cache.enabled.com.liferay.portal.model.User=false
# Disable finder caching for User
value.object.finder.cache.enabled.com.liferay.portal.model.User=false

Disabling the Hibernate cache is much more tricky; in order to accomplish this, it is necessary to modify the Hibernate mapping file in order to disable caches on a per-class basis for all implementation classes related to the model object.  This requires you to extract the META-INF/portal-hbm.xml file from the portal-impl.jar file distributed with the base Liferay portal application, make the appropriate modifications to that file, and then repack the file back into the jarfile.  In order to disable User caching, it is necessary to locate the <class name="com.liferay.portal.model.impl.UserImpl" table="User_"> entity within this file, and remove the following child element from the XML:

<cache usage="read-write" />

This will instruct Hibernate not to create a cache for the UserImpl persisted object, as is standard for any development project using the Hibernate framework.

Obviously, this third step is relatively onerous from a maintenance standpoint; directly modifying files stored in any of the Liferay-supplied library jars requires that the same modification process be followed any time an upgrade or fix is applied that updates this jarfile.  Additionally, disabling caching like this may have significant negative repercussions on portal performance; database access is a costly operation, and it’s generally a best practice to store frequently-accessed data in an in-memory cache if possible.