The following are are main requirements for vFabric gemfire implementation for a large financial institution here in bay area .
1) Build a framework using the Spring AOP, to optimize the application using vFabric gemfire. The application might cache data from database or any other source.
2) Use topology which provides the vertical scaling
3) Use lazy-initialization for domain objects – Hibernate Objects might use lazy approach for loading the objects. Develop an approach to handle transient objects in application.
4) Apply plugin architecture with opportunity to disable GemFire at any time. This is an ON/OFF switch required for the cache implementation and uses AOP interceptor mechanism.
5) CacheServers has to be configured without application code. This requirement forced us to use latest PDX(portable data exchange of Gemfire)
Generic Framework
The following are the general approach for a cache implementation. The complete design I will be blogging in my next post
User Interface interacts with Data layer using JPA Repository methods. JPA Repository methods are intercepted using Spring AOP. Spring AOP routes the calls to gemfire APIs. If the data is found in the cache, it is returned to the customer, else data is fetched from the database and stored in cache before returning data to user interface.
Client-Server topology
please read the blog for more details http://consultingblogs.emc.com/manjunathasubbarya/archive/2011/11/27/topologies-options-with-vfabric-gemfire.aspx
Handling Lazy Interception of Repository method calls using Spring AOP
In our example we have Account and Address domain objects with relation OneToMany with Lazy fetch strategy.

In our example we have Account with business logic in getAddresses method. We can’t intercept method getAddresses because in this case we need to implements business logic in interceptor. The solution is to create additional method getAllAddresses with simple return value and intercept this method. Additionally we need to change code in getAddresses method in order not to use field addresses directly and always call getAllAddresses method.
Second option is to intercept method getAddresses and using reflection API to access to field addresses directly. In this case we will have this logic:
1) Check is collection a PersistanceBag
2) Load childs from database
3) Set field addresses by reflection API
The method getAddresses in Account object is returning list of child objects. The method getAccount in Address object is returning Account object. With LAZY fetch Hibernate creates objects with javaassist proxy that automatically loads referenced objects from hibernate session. In this case we need to store additionally IDs for Account and back reference to Addresses according Limitation 3.
Gemfire objects:
We are creating two gemfire cache regions for separate storing parent and child objects:
1) accounts
2) addresses
<region name="accounts">
<region-attributes refid="CACHING_PROXY" scope="distributed-ack">
</region-attributes>
</region>
<region name="addresses">
<region-attributes refid="CACHING_PROXY" scope="distributed-ack">
</region-attributes>
</region>
The idea why we are doing this separately is to manage updates for address and all other child objects separately. In this case we could make read only collections of childs and manage all updates in their own repositories. We will intercept all methods that finds and saves objects in child repositories and will simply update them in cache. Also we have Limitation 4 where we need lookup by childId.
Each region will have CacheLoader on client. We will not use queries and OQL for retrieving object from Cache and we don’t need to guarantee that all objects are in cache. In this case all requests will be get and puts by key. GemFire will invoke CacheLoader if object is not in cache. In this case we will load object from database.
Each time where somebody access getAddresses() from Account we need to make lookup addresses by Id (we can’t use queries to avoid preloading data to cache). In this case we need to store Ids for addresses. The solution is to store in AccountCache object the list of AddressIds. We need to maintain this list and make them lazy loaded to cache. At first time where getAddresses method will be invoked, we will go to database and retrieve all addresses for Account.
Predefined JPA queries could improve productivity. We are using AOP to intercept getAddresses method, in this case Account object that we are returning to application has to be AOP proxy. We are intercepting AccountRepository method findById and creating account proxy in this method.
If object not found in cache, GemFire will invoke AccountCacheLoader and automatically loads object to cache. Account object loaded specially with Lazy initialized collections and it will be very light.
Proxy Account object intercepts methods that returns child objects, for example getAddresses().
This method has a realization that is loads AccountCache object and checks AddressIds collection of back index. If collection is null, then we load all data from EntitiyManager, update collection with AccountCache object and addresses region.
When we save Account, we need to check is it a proxy object. If yes, we need to get targetObject and save it in Hibernate. Empty child collections will be guarantee that we will not change childs in database.
Child updates are done by intercepting ChildRepository save method. In this method we are updating in AccountCache object Ids collection and updating child region with database.
All child collections like getAddresses we are making un-modifiable.
Plugin-architecture
As the application is designed on the basis of interception commenting few lines configuration turns of the whole cache implementation.
PDX Serialization
vFabric GemFire's Portable Data eXchange (PDX) is a cross-language data format that can reduce the cost of distributing and serializing your objects. PDX stores data in named fields that you can access individually, to avoid the cost of deserializing the entire data object. PDX also allows you to mix versions of objects where you have added or removed fields.