EclipseLink's object caching solution is one of its most unique and powerful features. While most persistence solutions choose to cache data rows and rebuild objects when a cache hit occurs, EclipseLink has gone further and caches entities with all the defined data conversions applied. This approach to caching greatly improves performance and reduces the amount of garbage created when accessing cached objects. The caching is also very flexible, allowing developers complete control over L1 and L2 cache usage, lifecycle, refreshing, cluster coordination and concurrency protection to minimize and handle stale data scenarios. As with all caching solutions the performance and scalability benefits are gained when the solution is tuned with respect to the applications usage of the data and the behavior of the underlying database, which is often shared with other applications in the enterprise.
EclipseLink caching can be configured using annotations or XML. Here is an example of how the @Cache annotation can be used:
@Cache( // Cache a number of objects with Hard references // and the remainder with Weak references type = CacheType.HARD_WEAK, // Number of Hard references to hold size = 500, // Store instances in the shared (L2) cache shared = true, // When changes are made to an object // invalidate (mark dirty) instances in other nodes coordinationType = CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS) public class MyEntity
One of the trade offs when using caching in a persistence solution is dealing with potential for stale data in the cache. While the application specific configuration of the cache can minimize stale data it is strongly recommended that you have a locking strategy using optimistic and/or pessimistic locking. Users of EclipseLink can leverage the standard JPA @Version mechanism for mapping a numeric or timestamp value in their entity to a column. While this is probably the easiest solution to manage from a mapping perspective, it does not always work with pre-existing schemas where additional columns cannot be added or other applications will not honor the optimistic locking semantics when modifying the database. To address these situations, EclipseLink JPA offers additional optimistic locking policies as well as pessimistic locking.
@Entity @OptimitisticLocking(CHANGED_COLUMNS) public class MyEntity
As shown here, an EclipseLink @OptimisticLocking policy can be specified on entities where no version column exists in the database and adding one is simply not an option. The CHANGED_COLUMNS policy in the example ensures that all columns changed in a transaction still have the same values in the database as when they were read. If any of the columns that are to be updated have been changed by another application, an optimistic lock exception is thrown. This is just one of a number of optimistic locking policies that are available to deal with different schemas and concurrent update scenarios.