Question

I use JBoss AS. I have a long and heavy SQL that run inside the application server. I want to cache the results based on input parameters.

I have a few options here:

  1. Use a caching manager and manually putting the results in the cache.

  2. Use a caching manager with loader that will "load" the results into cache when there's no results in cache.

I don't care for now about replication of the cache to other servers in cluster.

My question is what option should I choose? What are the benefits and drawbacks of each option. (ease of deployment, configuration mess)

Is this can be implemented using JBoss Cache or ehcache or both.


Update: I am using hibernate but the results are not entities, they are counters. I need to count all rows that belong to specific category and have specific status. I want that result to be cached.

Should I wrap the results inside an entity? Then, how can I make it work like (materialized?) view in oracle - to be update automatically or by trigger.

Was it helpful?

Solution

You're going to have to get the data out of the ResultSet and into objects in order to cache it so why don't you just start using Hibernate, which provides caching using a verity of options inclucing Ehcache, JBoss Cache and a simple Map.

http://docs.jboss.org/hibernate/core/4.1/manual/en-US/html/ch20.html#performance-cache

OTHER TIPS

For starting a WeakHashMap can probably do what you need for now.

Create two classes, a Key holding the values needed to identify the key (remember to implement equals() and hashcode()), and a Value holding the retreived values as pulled out from the ResultSet. The easiest is probably a List of Maps (a map per row).

Java will automatically invalidate the entries when running out of memory in a WeakHashMap.

If you just want a quick roll-your own caching solution, have a look at this article on JavaSpecialist, which is a review of the book Java Concurrency in Practice by Brian Goetz.

It talks about implementing a basic thread safe cache using a FutureTask and a ConcurrentHashMap.

The way this is done ensures that only one concurrent thread triggers the long running computation (in your case, your SQL call). Without doing something like this, then you are in danger of multiple threads triggering your SQL call when your cache is empty, e.g. if you are under heavy load immediately after you've started your app server. Obviously, its up to you to judge if that is a problem for you, or if you'd be happy a simpler solution where the last thread to complete puts its result in the cache.

You'd have to modify this solution to add cache expiry if you need it. Also, it wouldn't release the memory, like Thorbjørn's suggestion of using a WeakHashMap.

There is no point in developing a wheel from scratch. I am using Google Guava Cache in big Java EE application and would definitely recommend it. You can read more from:

https://code.google.com/p/guava-libraries/

and directly about the Cache:

http://guava-libraries.googlecode.com/files/JavaCachingwithGuava.pdf

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top