3

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?

Community
  • 1
  • 1
ayang
  • 446
  • 6
  • 22

1 Answers1

2

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
  • 54,009
  • 15
  • 113
  • 152
  • 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 Jul 06 '09 at 15:37
  • 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 Jul 06 '09 at 15:55
  • 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 Jul 07 '09 at 12:24
  • Terracotta is a *clustering* solution, not a caching one – oxbow_lakes Jul 08 '09 at 06:19