views:

79

answers:

3

I have the java servlet that retrieves data from a mysql database. In order to minimize roundtrips to the database, it is retrieved only once in init() method, and is placed to a HashMap<> (i.e. cached in memory).

For now, this HashMap is a member of the servlet class. I need not only store this data but also update some values (counters in fact) in the cached objects of underlying hashmap value class. And there is a Timer (or Cron task) to schedule dumping these counters to DB.

So, after googling i found 3 options of storing the cached data:

1) as now, as a member of servlet class (but servlets can be taken out of service and put back into service by the container at will. Then the data will be lost)

2) in ServletContext (am i right that it is recommended to store small amounts of data here?)

3) in a JNDI resource.

What is the most preferred way?

+1  A: 

From those 3 options, the best is to store it in the application scope. I.e. use ServletContext#setAttribute(). You'd like to use a ServletContextListener for this. In normal servlets you can access the ServletContext by the inherited getServletContext() method. In JSP you can access it by ${attributename}.

If the data is getting excessive large that it eats too much of Java's memory, then you should consider a 4th option: use a cache manager.

BalusC
+2  A: 

The most obvious way would be use something like ehcache and store the data in that. ehcache is a cache manager that works much like a hash map except the cache manager can be tweaked to hold things in memory, move them to disk, flush them, even write them into a database via a plugin etc. Depends if the objects are serializable, and whether your app can cope without data (i.e. make another round trip if necessary) but I would trust a cache manager to do a better job of it than a hand rolled solution.

locka
Might not be the most "obvious," but it's quite sensible.
erickson
It can also deal with the "warming up" i.e. reading from mysql, and the background updating. Takes a fair bit of reading, but it would be super clean in the application code.
Peter Tillemans
+2  A: 

Put it in ServletContext But use ConcurrentHashMap to avoid concurrency issues.

Bozho
JNDI is going to depend on the provider, and is most likely *not* identical. But as a member of the `Servlet` or in the `ServletContext`, makes no difference storage-wise, only in how it can be accessed.
erickson
@ericson - storage-wise, yes. But as it's not identical due to the remark of the OP, I removed that part :)
Bozho