Hibernate, ehCache and Caching

Hibernate uses caching internally. There’s always a trade off when you use caching. Without caching one observes slower times for execution, but will use less memory. Memory caching may impact the entire server or application if it runs out of memory, and memory size affects overall performance. Caching tens of thousands records doesn’t seem to be a good idea. I would imagine that ehcache has the capability to cache selectively, for instance cache some rows that are frequently used, instead of caching the entire table and strike a balance between acceptable memory taken and good speed too. If the same rows are retrieved numerous times, it is a good idea to cache those, however if different rows are retrieved each time, then it doesn’t make sense.
If the rows involved are in the thousands I would say, it is not a good idea to cache the whole table. iIt may be useful to investigate caching partially selectively based on LRU algorithm for instance. If the same rows are read again and again then we go for selective caching. If different rows are being read each time a lot of it depends on the application behavior. ehCache has some great caching techniques for selective caching of which most common is LRU (Least Recently Used algorithm)
Let us say maximum size of cache is 10 rows, a hypothetical number. Let us say User 1 reads rows 1, 2, 3, 4, 5. These rows are cached. User 2 reads rows 21, 22, 23, 24, 25, these rows are cached as well. Then if User 3 reads 31, 32, 33, 34, 35 these rows will be cached but the first five rows 1,2,3,4,5 will expire from the cache, since max number is only 10.
So if we go on calling any of 1.2,3.4.5 then we have good caching, number of hits is more. However if another user now asks for 1,2,3,4,5 and they are not in the cache, then it is a miss and these will be reloaded. So there is some tweaking that can be done about size limit.
maxElementsInMemory=”300″ means the max limit (10, in our example). memoryStoreEvictionPolicy=”LRU” is the least recently used algorigthm. There may be other algorigthms that ehCache supports.

From this http://www.mydeveloperconnection.com/html/spring-hibernate-QnA.htm :

Caching is widely used for optimizing database applications. Hibernate uses two different caches for objects: first-level cache and second-level cache.
First-level cache is associated with the Session object, while second-level cache is associated with the Session Factory object. By default, Hibernate uses first-level cache on a per-transaction basis. Hibernate uses this cache mainly to reduce the number of SQL queries it needs to generate within a given transaction. For example, if an object is modified several times within the same transaction, Hibernate will generate only one SQL UPDATE statement at the end of the transaction, containing all the modifications.
To reduce database traffic, second-level cache keeps loaded objects at the Session Factory level between transactions. These objects are available to the whole application, not just to the user running the query. This way, each time a query returns an object that is already loaded in the cache, one or more database transactions potentially are avoided. In addition, you can use a query-level cache if you need to cache actual query results, rather than just persistent objects. The query cache should always be used in conjunction with the second-level cache. One of the open source cache implementation that Hibernate supports out-of-the-box is EhCache.

EHCache is a fast, lightweight, and easy-to-use in-process cache. It supports read-only and read/write caching, and memory- and disk-based caching. However, it does not support clustering.

To activate second-level caching, you need to define the hibernate.cache.provider_class property in the hibernate.cfg.xml file as follows:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.cache.provider_class">org.hibernate.cache.EHCacheProvider</property>
    </session-factory>
</hibernate-configuration>

By default, the second-level cache is activated and uses the EHCache provider. To use the query cache you must first enable it by setting the property hibernate.cache.use_query_cache to true in hibernate.properties.
Example http://cuppajavamattiz.com/2007/09/16/using-mysql-ds-xml-and-applicationcontext-data-with-the-hibernate-example/ in applicationContext-data.xml.
Configuring Hibernate Cache
We specify which classes to cache and the caching params but we don’t really write code to invoke the cache.
http://www.informit.com/articles/article.aspx?p=353736&seqNum=5 #Configuring a Cache.
If you feel certain that the problems are due to the amount of traffic between your application and the database. The solution in this case may be a cache. By storing the data in a cache instead of relying solely on the database, you may be able to significantly reduce the load on the database, and possibly to increase overall performance as well.
Regardless of which cache you choose, you will need to tell Hibernate what sort of cache rules should be applied to your data. This is defined using the cache tag. You can place the cache tag in your *.hbm.xml files or in the hibernate.cfg.xml file. Alternatively, you can configure cache settings programmatically using the Configuration object.

About cuppajavamattiz
Matty Jacob - Avid technical blogger with interests in J2EE, Web Application Servers, Web frameworks, Open source libraries, Relational Databases, Web Services, Source control repositories, ETL, IDE Tools and related technologies.

Comments are closed.

%d bloggers like this: