I'm having some considerable difficulty figuring out what to do with a problem I'm having in an application we're building.
The application is basically displaying data from a database (updated by another separate application) on a UI and provides navigation of that data.
We have many refresh areas on the page, several of which are updated at different times during navigation. These range from a Tree control to a breadcrumb trail and a mix of other contextual data.
The object graph is very large, and we must aggressively lazy-load. The database is also very complex and the queries required to load data are fairly slow running - which makes lazy-loading even more important. And we need to be careful to display as up-to-date data as possible, so we are regularly hitting the database to re-read data.
So here comes my problem. Ajax requests cause concurrent access to objects, so we have multiple threads on the server dealing with basically the same objects even within the same user session, all to refresh different parts of the UI as the user clicks around and various Ajax regions auto-refresh.
So we get these LazyInitializationExceptions, because we end up quite often with two different Session beans trying to service two different requests and trying to lazy-load two different parts of the same bean to service different refresh areas.
We've tried all we can to serialize access to these beans with extensive use of @Synchronized annotations through our Action classes and this has cleaned up the majority of these kinds of problems, except what we're seeing now when two different @Synchronized components need to lazy-load two different parts of the same bean, and we end up with threads fighting to associate the same object each with its own Hibernate session, and then KABOOM.
So, I'm sitting back thinking. What am I missing?
I hate the idea that in order to solve these problems the end result seems to be serializing all requests through a single @Synchronized Action component so that we never process requests concurrently that might need to reconstitute different areas of the object graph. Never mind the performance implications of this (why am I being forced to effectively write a single-threaded app???!!!), I just hate the way this whole antipattern is developing.
So again, what am I missing? I need some concrete ideas or examples of how to break this spiral.