views:

213

answers:

1

Similar to this thread, but not exactly: How To Cache Information In A Threadsafe Manner

What is the usual pattern for dealing with "reference data" - data that is frequently read by an application, usually externalized in a database or properties file, but updated very infrequently (days, weeks, months)? When the data is updated, it would be updated externally.

Would this normally be a singleton that I could inject with a DAO and would thus be able to manage its own contents? I like the idea of exposing a refresh() method on this service that would force a refresh (i.e., through an MBean - so I wouldn't have to bounce the application).

From the other SO thread, it sounds like people might just instantiate the DAO's whenever necessary and cache transparently at that level.

I kind of like the idea of the singleton service being injected with either a real DAO that loads data from the database, or else a mock/test-double that returns a hard-coded response. However, if I were to implement the service as a singleton via java enum's, this makes wiring it up via Spring a bit more problematic.

So, how do other people typically deal with reference data? Query-at-will but with caching under the covers? Or a separate in-memory service?

+1  A: 

I typically inject a DAO implementation into my service layer using Spring and, as you mention often have a test implementation (XMLDao, FlatFileDao) in addition to my SQL-based implementation. For small datasets I usually write my own cache and store all data loaded from the underlying table(s) in memory.

Saying all that, I have the advantage of working with reasonably small datasets. If I were dealing with a larger dataset I may consider off-the-shelf caching solutions, possibly distributed across multiple JVMs (like Terracotta).

As I mentioned in the previous thread I also expose a refresh() method. In cases where updates to the data do not need to propagate in a timely manner I simply call this manually via an MBean. In situations where I wish to automate this I've used Tibrv to listen to updates from the database and refresh the cached data (using an MS-SQL trigger to generate a Tibrv message).

I don't quite understand your reference to using Java enums to implement the service - How would this work?

Adamski
I may have muddied the waters with that part. Mainly, I'm wondering about injecting dependencies into singletons. Now that I think about it, this might be a separate question.Anyways, according to Bloch, the current best practice for implementing singletons in java is with Enums with a single member (the instance): i.e. public enum Elvis { INSTANCE;}
ayang
If you were to go down this route couldn't you still inject any dependencies via Spring using MethodInvokingFactoryBean to call the relevant setter on the enum class?
Adamski
Yes, and that is what I will likely end up doing - but it was inelegant enough that I thought I'd go back to first principles and see if I was doing this wrong.
ayang
Terracotta is a *clustering* solution, not a caching one
oxbow_lakes