views:

122

answers:

5

In my application, I am storing a small table containing 50 records in a singleton class because the data in this table hardly changes - e.g. the list of countries.

Although, the concept is not good, I have to continue with it right now. Is there any solution in Hibernate which observe change in the table and on change, invoke a method of a class to update the variable.

+1  A: 

Implement Interceptor#onFlushDirty(). Ah no, you want to do it from the other side on. No, it's not possible. Best what you can do is to reload the data at certain intervals, for example once every hour. You can use java.util.TimerTask for this.

That said, a Singleton is really a bad idea. Just have it as some kind of an attribute of the main context. If it is for example an Java EE webapplication, you can use ServletContext for this.

BalusC
+3  A: 

Hibernate won't get notified of changes made at the table level. The (bad) solution would be to update the data through Hibernate's API and to use one of the callback provided by an Interceptor to do some black magic voodoo with the Singleton. But honestly, the (right) way to handle this would be to get rid of that singleton and to put the data in 2nd level cache (and to invalidate the cache if you update the table manually).

(EDIT: As ChssPly76 mentioned in a comment, there is an intermediary solution if removing the singleton is not an option which consists in modifying the singleton to find and return cached hibernate-managed entities like your countries for example.)

Pascal Thivent
+1 for 2nd level cache. OP doesn't even have to get rid of the singleton if it's tied into code; it should be trivial enough to refactor it to get stuff from the cache.
ChssPly76
Absolutely true, answer updated accordingly.
Pascal Thivent
A: 

It seems that easiest approach to this is a trigger on the database end instead inside of your application. But this depends of course on the underlying database and if you really want to use SQL if everything else is done by Hibernate.

pmr
A trigger won't help to call a method on a singleton. I'm not sure what you have in mind.
Pascal Thivent
+1  A: 

Your situation sounds ideal for the L2 cache since your objects rarely change and set your expulsion policy accordingly to refresh. Further if ALL mods are done through Hibernate then you can keep track of what happens through the events/interceptor infrastructure. Of course, any auxiliary tables Hibernate does not know about would have to be tracked by other means like how @BalusC suggested.

non sequitor
+1 for cache; there's no need to mess with expiration or interceptors - it'll all happen auto-magically. For auxiliary tables (if there are any), the only reliable way is to have predefined entry points and manually notify all of possible changes; basically the same L2 cache but (if need be) distributed.
ChssPly76
Kudos from @ChssPly76 on a Hibernate issue -- made my day right there :)
non sequitor
A: 

Everybody keeps repeating the chant about Singletons being evil, but this mainly goes for old fashioned (private constructor + getInstance method) Singleton implementations, their main drawbacks being hard to unit test and not robust in multi-threaded or clustered environments. However, Spring offers a perfectly valid possibility for 'singleton' beans within its context. Just because there are issues with some (very mainstream and heard to root out) implementations does not mean the Singleton pattern is always bad.

Adriaan Koster
First, I don't see how this does answer the question. Then, believe it or not, the singleton pattern is **not** the right way to cache data from a database, there are better ways to do this, especially when using Hibernate. Finally, who said that "Spring singleton" shouldn't be used? I get your point but I don't think this is the right place to advocate it.
Pascal Thivent
You are right - I was just in the mood for a pattern rant. My apologies.
Adriaan Koster