I have a fairly general issue that I could do with some guidance on. Basically I am developing a webapp using servlets for use on a company intranet. I obviously want to keep the development of this system as OO as possible, and so am looking at designing various beans whose state would be populated from a database. A typical page request would therefore see one, or more, objects being populated with data from the db and then being used to fill the content of the page. The objects would then be saved to the session for further use on the same, or different, pages. Nothing hard about that! The area I am unsure about comes from the scenario where 2 different users could request the same page and therefore 2 new instances of the same object which would then be saved into each user's session. If user A were then to change the state of his instance of the object (saving the change to the database) then his object would be current and up to date, but user B would still be using his original object which was populated with data that is now out of sync with the database. So what is the best solution for ensuring that all user's objects, placed in sessions, always remain populated with the most current data, or that all user's objects become aware that they need to refresh their data?
I am sure this isn't a new issue, but I'm at a bit of an impasse now and not sure where to go. Is this an area where Hibernate or JavaBeans (or some other groovy java tool) would come into play? Does anyone have any suggestions of useful resources to look at?
Can you explain what you intend to do in the following scenario:
User A - creates the session (db fetch) Updates some attributes of the object (but not committed)
User B - Creates the session (same record fetched by User A) Updates some attributes
User A - commits the object. Now the object in User B session is stale.
This object should not be refreshed from the db otherwise User B will lose the updates. You can find the object in User B is out of sync before updating (by maintain two copies of attributes with old value and new value and select the record from db and check if old value in session matches with the db row) and report back to user. Is that what you want to do or refresh the object in User B session (this doesn't sound like good idea)?
Joined: Jan 11, 2006
Thanks for the reply. Although the issue you raise is pertinent (and its given me more to think about!), i'm not sure if its one that I am overly concerned with at the moment. The scenario I thinking about involves:
User A - creates the session (db fetch) User B - Creates the session (same record fetched by User A)
User A - Updates some attributes of an object and commits the object. User B - makes no changes to the object, but as his object remains in the session he continues to show the original data and not the data updated in User A's commit for the duration of B's session.
What mechanism can be put in place to force User B's object to check for updates to the database, or just changes to fields that relate to is's structure? Or are there mechanisms / tools around that can be implmented to automactically take care of this role?
I am beginning to think that this is actually more of a object relational mapping problem and is going to require me digging into JavaBeans / Hibernate etc a bit more. My limited understanding of Hibernate for example, is that you create objects that map to entities within your database, and I guess these are what you would then make available to each user's to display data. Hmmmm, need to read more!
A few things to think about if you decide to roll your own:
The simplest solution is, of course, to not cache the data at all; just fetch it from the DB every time you need it. Are you going though all this because you think there might be a performance issue? Generally I've found that just hitting the database each time performs quite adequately and only start coming up with caching techniques when observable performance problems manifest themselves.
If the data is not user-specific, why cache it in the session? If the data is the same for each user, cache a single copy in application scope.
If you are going to cache data, don't use the cache as a write-back mechansims. Keep it simple and make your caches read-only. Make the changes directly to the DB and use customary caching techniques to make sure that the cached objects know when they are invalidated and need to refresh themselves from the DB.
Simpler is better. Only make your app as complex as it really needs to be. [ January 19, 2006: Message edited by: Bear Bibeault ]
If you are not concerned about updated object in session B then you have to pull the data from db and refresh the object in the session for every request. Instead of coding this step in every servlet it will be better to write a Filter which peeks into the session objects (you may have to use reflection) and refresh the data.
If you are too concerned about the frequent db queries then you can think about using Object cache for the db row. In this case you have to write a listener/observer for db row object and update the cache when user commits the record.
Originally posted by Purushothaman Thambu: then you have to pull the data from db and refresh the object in the session for every request.
Then what would be the point of caching the data in the session in the first place?
Joined: May 24, 2003
You are right, the object don't have to be in session scope. It can also be in request scope. I got carried away!...
Joined: Jan 11, 2006
Thanks for your replies and suggestions. Bear Bibeault you are entirely correct that simply not caching the data is the easiest option and its what I currently do on all my other projects. The reason i'd like to cache data is that in some cases a reasonably complex object has to be loaded for a particular page, or set of pages, that a user might access on quite a frequent basis. Obviously at face value loading the object once and then persisting it is much less labour intensive than querying the db and creating new instances of the same object for multiple pages. (Of course I should also start looking at simplifying my objects / data querying / page design & flow .
I did also consider caching data like this in the application scope, but we're talking here about potentially many hundreds of instances of different objects over time. My understanding of the application scope is that it should mainly just be used to hold data common to the whole application that is generally loaded on startup. (but I could be wrong on this!)
I like your idea of making the cache read only. You mention
customary caching techniques
, do you think you could give me an example / pointer to somewhere with examples?
Anyway, thanks again to you both for your suggestions. Like most things, a deceptively simple sounding problem!
My understanding of the application scope is that it should mainly just be used to hold data common to the whole application that is generally loaded on startup. (but I could be wrong on this!)
From what you have posted, doesnt your data fall into this category? If it isnt common to the whole application, why should one user update the data in his 'session' when another user does so through the front end?
I did also consider caching data like this in the application scope, but we're talking here about potentially many hundreds of instances of different objects over time.
Dont the same objects exist in the session too and when it is sessions, it will be hundreds of such objects per user rather than one instance in the application scope.
customary caching techniques
Take a look at open symphony cache and/or jboss cache. But wont you require to store the cached objects too somewhere? And if you are thinking of storing it in each user's session, all users will have a refernce to the same object. An easier option would be application scope as Bear suggested.
I have not read the full thread. I have only read the first posting. I feel you can use place the object in application scope instead of putting it in session scope. Then both users will be able to access the most updated object.
�That which begins, also ends.�
Adeeb Abdul Karim
Joined: Dec 22, 2004
I feel application scope does not only mean the objects loaded at start up. Any thing which is needed to be shared across the application, ( across sessions, across requests .. ) can be placed in application scope.
In your case, I think the object is accessed by more than one user. So a synchronised object in application scope will be a good choice it seems.
When I originally started thinking about this problem my initial idea was to do as several of you have suggested and store my data in the application scope as synchronised objects. I was dissuaded from doing this after reading on another post somewhere on javaranch (can't seem to find it now) where someone had stated this was bad practice, hence why I then posted this thread. I think I may therefore have been a bit hasty in taking what they had written at face value!
Thanks for all your advice (+ the links to the JBoss Cache), I think I shall just put together a test implementation of the Bear's suggested approach and see how it goes from there!
You really need an application scope cache... You might look at EhCache too, it's the default cache for hibernate, and it does a decent job and has some niceties, like xml configuration and thread safety. While you're at it, you might consider using hibernate as your DAO framework... Among lots of niceties, you will get transparent and configurable caching.
But in away way, caching does involve the potential for loss of synchronization. Hibernate will behave nicely, as long as *only* your application updates the data. If data is updated from some other source, you will have to deal with potentially stale data...