Since our book focuses on strategies for building scalable, production-ready applications, caching strategies are an important topic in our book. It's difficult to give you an accurate answer to your question, as there is no perfect caching strategy. It really comes down to your application's requirements. If you are building an application that will be deployed in a clusterable configuration, you may want to consider a caching implementation that is cacehable. We recommend ehcache, as it supports several clusterable caching configurations, using either RMI, JMS, or jgroups. The advantage of a clustered caching strategy is that it can prevent the potential for stale content, as a clustered application in which each node in the cluster uses its own private cache, an update to the database won't be propagated to the caches of other nodes in the cluster. This can lead to stale content and version conflicts. Additionally, without a clustered caching configuration, you will continue to put additional load on the database, increasing with each node added to the cluster.
More important than the caching provider is how effectively you tune your caching strategy. For instance, selecting the appropriate TTL, cache size, and expiration model can have a dramatic effect on your application's performance. Misusing caching can actually degrade performance, and is a common pitfall. For instance, if you cache too many objects, you will likely run into memory issues or GC thrashing. Also query caching can be an effective optimization or a serious performance problem as well.
Hope this helps!
Paul Tepper Fisher