As I tried to explain before, moving complete POJO hibernated objects between the app server and the client every time the client wants to read objects that are persistent will not be acceptable performance-wise. The client will rarely be on the same machine as the server and occasionally will even be on another network. This will be an interactive client and responsiveness will be important.
After some reading, I believe what I am going to attempt to do is as follows:
I will set up a local copy of hibernate on the client-side. The server will have its own instance running inside the application server. The client-side copy will be READ-ONLY. In fact, I plan to avoid even performing actual queries (find()) themselves on the client-side. Instead, the application server will only ever send identifier (primary key) values to the client. The client instance of Hibernate can then load (and CACHE) objects directly from the data-source. Since updates and inserts will be far less frequent than reads on the client-side, it is acceptable to serialize and ship new and updated objects to the application server and use its instance of Hibernate to persist the new/updated objects. Using OSCache should allow me to keep the caches of the clients consistent with that of the server.
Actually, scratch that idea. As I was writing this, I thought of something perhaps better:
If all I'm going to be doing on the client side instance of Hibernate is to use it as a cache, how difficult might it be to use OSCache's APIs directly on the read-only client side and have the server's Hibernate-connected instance of OSCache serve as the cache master?
For example, let's say the client wants object A. To start off with, the client has an empty OSCache that it is utilizing directly (without Hibernate). The application server has an empty OSCache that is connected through Hibernate. These two OSCaches are configured to both subscribe to the same JMS Topic.
First, the client checks its local OSCache for A and doesn't find it. It then requests object A from the application server. The application server loads object A. This implicitly places it in the application server's OSCache. It then serializes and sends object A to the client. The client places this object in its OSCache, then displays it to the user, for example. An external force then causes the application server to change object A. The application server's Hibernate-connected OSCache is notified and the notification is passed over JMS to the client-side OSChache, which invalidates object A on the client.
Does this sound reasonable, or does Hibernate interoperate with OSCache in a manner that would make it difficult for a 'plain' OSCache to interoperate with?
This seems to give me all the benefits that I want:
1) Changes to persistent data MUST happen through the application server
2) Access control to business objects will still be centralized within the application server
3) Business objects may be cached on the client side, EVEN between invocations of the client, so long as OSCache was configured to use the disk and a synchronization routine was invoked at client startup to invalidate stale items in the cache.
4) Database activity would be minimized since the application server could serve its own cached instances of persistent objects to the client.
I would probably need to set up a method for the server to decide if it should send full objects or only identifiers as the result of a query so that it can avoid sending objects to the client that it can be pretty sure are already cached. If the objects aren't cached, the client would have to make a second request to the server to retrieve the objects it's missing. This doesn't seem to bad, though. I see no reason why the server wouldn't be able to accurately track what objects the client already has in-cache anyhow.
Does any of this seem sensible to people?
|