Caching/DAO layer architecture question
I'm trying to design a new, basic Data layer for our Java web-application, following the DAO pattern, and at the same time implement OSCache for object caching. http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
Any advice on the following points? (Only looking for high-level architectures comments, as I've already dealt with many technical specifics)
- How tightly integrated should the Cache layer and the DAO layer be? Should they be one and the same?
- Related to the first point, should the DAO layer manage the Cache, by putting things in the cache, and flushing them when necessary? Or should the "client" manage the cache?
- One pattern I've seen is where the Cache is accessed by the "client", and if there is a cache miss, the Cache layer accesses the DAO layer and populates the Cache. What do you think about this? Just depends on the application?
- Where would be a good place to ask this question? haha, I'm not very clued in on whatever forums are out there...
AI Summary
5 Comments
BOOOOOOOOOOOORRRRRRIIIIIIIIIINNNNNGGGGGGG!!!!
"- One pattern I've seen is where the Cache is accessed by the "client", and if there is a cache miss, the Cache layer accesses the DAO layer and populates the Cache. What do you think about this? Just depends on the application?"
I've implemented a framework this way. I've got something called a CacheManager (which is the brains) which calls a CacheLoader (which accesses the datasource (whatever it is)) when there is a miss to populate the cache.
now this is more of a "client cache" strategy, which not only cuts down on database access, but on the potentially costly communication between the "client" and whatever service you are using, for instance EJB.
Another way could be to cache much closer to the database, or within your DAO layer, Hibernate, for example, can use a cache (EHCache is one choice). I really don't know much about Hibernate, so I can't give you any technical details on this.
oh, and the main entrypoint is a class that represents a proprietary "SystemCache" (not bound to any particular tech). There is basically one method "get(Object key)". This class delegates to the CacheManager, which looks to see if its in the third-party (JCS) cache. If not, it uses the CacheLoader associated with our "SystemCache" object to get it from whatever source.
This is the thing: you write custom CacheLoaders (which is only an interface with one method "loadCacheObject(Object key)) that can get the data whatever way you want. EJB, DAO, text file, http, whatever. the criteria it uses is contained in the key, which can be a String or a non-String class with several fields.
Ok, cool. This is basically the pattern we've started using based on this article. http://www.javaworld.com/javaworld/jw-05-2004/jw-0531-cache.html
So, the client should call the CacheManager, which should call the CacheLoader for that object, which should call the DAO.
If a particular object is not to be cached, it should just call the DAO directly.
yeah, except I've created another "layer" I guess in the "SystemCache" object which owns a reference to the CacheManager and the CacheLoader.
this way your client only needs to call the following:
Object myObj = widgetCache.get("widget1"); (either returns the object, or null if either no object found in data source, or if an exception is thrown, therefore, it looks sort of like a read-only HashMap)
widgetCache was created previously somewhere as:
SystemCache widgetCache = new SystemCache(JCSCacheManager.getInstance(), WidgetCacheLoader.getInstance());
I'm using spring, so we don't create the SystemCache in this manner in our code, but this is the aproximate syntax.
by