what to store in session?
Consider following situation. User is logging into web application. What to store in session? 1. User object - it can be a large one (about 30 attributes, Strings, associated Objects). In this situation will be only one request to database (on user logon). Then all data will be taken from this object. 2. Put in session only user unique identifier (key) and then load neccessary data from database only when it's requested. Which one is better approach? md -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: what to store in session?
I would say it depends. How expensive is a database hit and how many times do you find the need to hit the database to retrieve data? Is all the data used all the time or is just some of the data used? In your application is it acceptible to have a slight delay while loading the users profile? Is the users profile subject to change by other entities/system during their session? (can the data become stale?) These are some questions you need to ask yourself which will help determine your course of action. If it is acceptible to load all 30 attributes at logon AND the data does not have a chance of becoming stale AND you have the memory to accomodate it, then I would choose solution 1. Of course, if the user edits their profile, you will have to synchronize it with the database. If just some (a small portion) of the user's data is necessary, then I may choose a lazy loading scheme. robert -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Wednesday, June 26, 2002 9:20 AM To: [EMAIL PROTECTED] Subject: what to store in session? Consider following situation. User is logging into web application. What to store in session? 1. User object - it can be a large one (about 30 attributes, Strings, associated Objects). In this situation will be only one request to database (on user logon). Then all data will be taken from this object. 2. Put in session only user unique identifier (key) and then load neccessary data from database only when it's requested. Which one is better approach? md -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: what to store in session?
Hi All, I'd add to Roberts very pertinent comments that Clustering as mentioned in an earlier post is also an issue here. If you intend to run your app in a cluster then session size becomes an issue; as your user object *may* be copied over the network to other machines. Also the projected number of concurrent users is an issue. Do you have enough memory (regardless of clustering issues) to hold all the user objects in memory? Jon Ridgway -Original Message- From: Robert Taylor [mailto:[EMAIL PROTECTED]] Sent: 26 June 2002 14:41 To: Struts Users Mailing List Subject: RE: what to store in session? I would say it depends. How expensive is a database hit and how many times do you find the need to hit the database to retrieve data? Is all the data used all the time or is just some of the data used? In your application is it acceptible to have a slight delay while loading the users profile? Is the users profile subject to change by other entities/system during their session? (can the data become stale?) These are some questions you need to ask yourself which will help determine your course of action. If it is acceptible to load all 30 attributes at logon AND the data does not have a chance of becoming stale AND you have the memory to accomodate it, then I would choose solution 1. Of course, if the user edits their profile, you will have to synchronize it with the database. If just some (a small portion) of the user's data is necessary, then I may choose a lazy loading scheme. robert -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Wednesday, June 26, 2002 9:20 AM To: [EMAIL PROTECTED] Subject: what to store in session? Consider following situation. User is logging into web application. What to store in session? 1. User object - it can be a large one (about 30 attributes, Strings, associated Objects). In this situation will be only one request to database (on user logon). Then all data will be taken from this object. 2. Put in session only user unique identifier (key) and then load neccessary data from database only when it's requested. Which one is better approach? md -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] The contents of this email are intended only for the named addressees and may contain confidential and/or privileged material. If received in error please contact UPCO on +44 (0) 113 201 0600 and then delete the entire e-mail from your system. Unauthorised review, distribution, disclosure or other use of this information could constitute a breach of confidence. Your co-operation in this matter is greatly appreciated. -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re[2]: what to store in session?
On Wednesday, June 26, 2002, 12:31:11 PM, Craig wrote: CRM * Do not store complete data structures that are large and complex, CRM unless they really represent shared application data (in which case CRM they should probably be in the servlet context attributes instead). CRM * Hide the caching choice you are making inside the get methods of your CRM user object, so you can change your mind later without modifying all CRM the code that uses the data. I know this is probably a pretty newbie question, but... How is it different storing something in the servlet context vs having a static member in a class that is only loaded once when null? In other words I'm tending to use your second approach above, where say I need a list of StoreBeans I call a getStores() from a Commons class that first checks if the StoresList is null, and if it is null it loads them up. Am I correct in assuming that subsequent requests by ANY other session to the getStores() method will not load them up once any session has called the method? If that assumption is correct, is the only difference then in storing a List in the servlet context a matter of being able to use the List on any JSP page without having to set it there first in some action class (as you would have to do with a List you got from a getStores() method in some class)? Thanks for the help Rick -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re[2]: what to store in session?
On Wed, 26 Jun 2002, Rick Reumann wrote: Date: Wed, 26 Jun 2002 14:19:52 -0400 From: Rick Reumann [EMAIL PROTECTED] To: Craig R. McClanahan [EMAIL PROTECTED] Cc: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re[2]: what to store in session? On Wednesday, June 26, 2002, 12:31:11 PM, Craig wrote: CRM * Do not store complete data structures that are large and complex, CRM unless they really represent shared application data (in which case CRM they should probably be in the servlet context attributes instead). CRM * Hide the caching choice you are making inside the get methods of your CRM user object, so you can change your mind later without modifying all CRM the code that uses the data. I know this is probably a pretty newbie question, but... How is it different storing something in the servlet context vs having a static member in a class that is only loaded once when null? If the class defining this static variable is loaded from the webapp class loader (/WEB-INF/classes or /WEB-INF/lib), there is not a lot of difference (although in Servlet 2.3 you have the option to use context attribute listeners to detect when attributes are added, removed, or replaced). If the class defining this static is loaded from a shared library directory (i.e. something like common/lib in Tomcat), then there is only one copy of the static variable for *all* webapps. Context attributes are always global to the entire webapp, but never shared across webapps, no matter how you organize your classes themselves. In other words I'm tending to use your second approach above, where say I need a list of StoreBeans I call a getStores() from a Commons class that first checks if the StoresList is null, and if it is null it loads them up. That's a good plan. My suggestion is to implement this logic inside a bean that hides whether or not you are really caching the data or not -- say a StoresBean something like this: public class StoresBean { public ArrayList stores = null; public synchronized Iterator getStores() { if (stores == null) { stores = new ArrayList(); ... fill in the objects in this list ... } return (stores.iterator()); } } That way, the relevant stuff will get loaded the first time and then reused. But your calling application doesn't know that -- all it needs to do is grab StoresBean out of the session attributes (if this is user specific) or context attributes (if this is global), and call getStores(). Am I correct in assuming that subsequent requests by ANY other session to the getStores() method will not load them up once any session has called the method? If that assumption is correct, is the only difference then in storing a List in the servlet context a matter of being able to use the List on any JSP page without having to set it there first in some action class (as you would have to do with a List you got from a getStores() method in some class)? If the StoresBean bean is in session scope, then getStores() will go load up the list once per user. That makes sense, for example, if the list of stores accessible to each user is different. You would want to create this bean, and store it as a session attribute, as part of your logon processing -- or make it a property of the user bean if you are already storing that in session scope. If the StoresBean bean is in application scope (i.e. a servlet context attribute), then getStores() will go load up the list the first time *any* user requests it, then everyone will share. This makes sense if the data is global to all users. You would want to create this bean as part of your application startup, by either: * In servlet 2.3, create a ServletContextListener and set it up in the contextCreated() method. * In servlet 2.2 or later, create a servlet that is configured for load-on-startup, and set it up in the init() method. * In servlet 2.2 or later, subclass the ActionServlet class in Struts, and override the init() method like this: public void init() throws ServletException { super.init(); ... initialize context attributes here ... } and use this as the controller servlet. Thanks for the help Rick Craig -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re[3]: what to store in session?
Thanks so much Craig, this has been tremendously helpful! Some comments below... On Wednesday, June 26, 2002, 2:38:54 PM, Craig wrote: CRM My suggestion is to implement this logic inside a bean that hides whether CRM or not you are really caching the data or not -- say a StoresBean CRM something like this: CRM public class StoresBean { CRM public ArrayList stores = null; CRM public synchronized Iterator getStores() { CRM if (stores == null) { CRM stores = new ArrayList(); CRM ... fill in the objects in this list ... CRM } CRM return (stores.iterator()); CRM } CRM } CRM That way, the relevant stuff will get loaded the first time and then CRM reused. Ok, you've started to clear some things up for me. I always thought thought that classes in my: myAppDir/WEB-INF/classes directory if they had static members they were shared across the entire application scope? This definitely is wrong though? (and it's only session scope?). In your above code, though, each user session would then end up loading a new list of stores. I don't really need that. I only need that list being loaded once and shared amongst all the sessions. CRM But your calling application doesn't know that -- all it needs to CRM do is grab StoresBean out of the session attributes (if this is user CRM specific) or context attributes (if this is global), and call getStores(). How would I grab this global attribute from a business layer object though? I guess that's where I'm getting confused. Say I have my Action class call a business object: BO.getStoresList() Well now I want the BO to return me a List of StoreBeans, but I only want that list populated ONE time and want all the sessions to share it.It looks like if I want all the sessions to share the information I have to pass servlet classes into my model layer? Am I wrong there? CRM If the StoresBean bean is in application scope (i.e. a servlet context CRM attribute), then getStores() will go load up the list the first time *any* CRM user requests it, then everyone will share. This makes sense if the data CRM is global to all users. You would want to create this bean as part of CRM your application startup, by either: CRM * In servlet 2.2 or later, create a servlet that is configured for CRM load-on-startup, and set it up in the init() method. Ok, I have set up some like this in the init() method of an IntializationServlet I call on startup: context.setAttribute( storeList, storeList ); CRM * In servlet 2.2 or later, subclass the ActionServlet class in Struts, CRM and override the init() method like this: CRM public void init() throws ServletException { CRM super.init(); CRM ... initialize context attributes here ... CRM } OK! Perfect this is exactly what I should do. Thank you. (I take it there weren't be any issues doing this to my controller which extends DispatchAction). Thanks Craig, Rick -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re[3]: what to store in session?
On Wed, 26 Jun 2002, Rick Reumann wrote: Date: Wed, 26 Jun 2002 15:16:11 -0400 From: Rick Reumann [EMAIL PROTECTED] To: Craig R. McClanahan [EMAIL PROTECTED] Cc: Struts Users Mailing List [EMAIL PROTECTED] Subject: Re[3]: what to store in session? Thanks so much Craig, this has been tremendously helpful! Some comments below... On Wednesday, June 26, 2002, 2:38:54 PM, Craig wrote: CRM My suggestion is to implement this logic inside a bean that hides whether CRM or not you are really caching the data or not -- say a StoresBean CRM something like this: CRM public class StoresBean { CRM public ArrayList stores = null; CRM public synchronized Iterator getStores() { CRM if (stores == null) { CRM stores = new ArrayList(); CRM ... fill in the objects in this list ... CRM } CRM return (stores.iterator()); CRM } CRM } CRM That way, the relevant stuff will get loaded the first time and then CRM reused. Ok, you've started to clear some things up for me. I always thought thought that classes in my: myAppDir/WEB-INF/classes directory if they had static members they were shared across the entire application scope? This definitely is wrong though? (and it's only session scope?). No, you've got that right. It's just that classes loaded from something like the common/lib dirctory in Tomcat are shared across *all* web applications, not just yours. In your above code, though, each user session would then end up loading a new list of stores. I don't really need that. I only need that list being loaded once and shared amongst all the sessions. Some people do need per-user-specific stuff for some things. The same design pattern works for both scenarios -- it's just a matter of where you store the bean (and how it builds the list of available stuff). CRM But your calling application doesn't know that -- all it needs to CRM do is grab StoresBean out of the session attributes (if this is user CRM specific) or context attributes (if this is global), and call getStores(). How would I grab this global attribute from a business layer object though? I guess that's where I'm getting confused. Say I have my Action class call a business object: BO.getStoresList() Well now I want the BO to return me a List of StoreBeans, but I only want that list populated ONE time and want all the sessions to share it.It looks like if I want all the sessions to share the information I have to pass servlet classes into my model layer? Am I wrong there? As a servlet context attribute, the simplest way would be to have your Action grab it (getServle().getServletContext().getAttribute()) and pass it to the business object. But we're getting into territory where there are a number of different approaches -- I would suggest consulting some of the good design pattern books like the J2EE Blueprints series from Sun, my favorite design patterns book Core J2EE Patterns by Alur, Crupi, and Malks, and others. The issues of how business objects get access to data (or JDBC connections, or ...) are universal, not limited to Struts apps or even web apps. CRM If the StoresBean bean is in application scope (i.e. a servlet context CRM attribute), then getStores() will go load up the list the first time *any* CRM user requests it, then everyone will share. This makes sense if the data CRM is global to all users. You would want to create this bean as part of CRM your application startup, by either: CRM * In servlet 2.2 or later, create a servlet that is configured for CRM load-on-startup, and set it up in the init() method. Ok, I have set up some like this in the init() method of an IntializationServlet I call on startup: context.setAttribute( storeList, storeList ); CRM * In servlet 2.2 or later, subclass the ActionServlet class in Struts, CRM and override the init() method like this: CRM public void init() throws ServletException { CRM super.init(); CRM ... initialize context attributes here ... CRM } OK! Perfect this is exactly what I should do. Thank you. (I take it there weren't be any issues doing this to my controller which extends DispatchAction). Well, you can certainly do it there ... but it feels sort of hidden away to me. You also have to be aware of thread safety for this, where the init() method (or servlet context listener) is guaranteed to complete before any request can be processed. Thanks Craig, Rick Craig -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re[4]: what to store in session?
Sorry Craig, I just realized I misread some of what you originally wrote. You were talking about sharing 'across' applications and I wasn't concerned with that so much. You can ignore my previous post. I apologize. Rick On Wednesday, June 26, 2002, 3:16:11 PM, Rick wrote: RR Thanks so much Craig, this has been tremendously helpful! Some RR comments below... RR On Wednesday, June 26, 2002, 2:38:54 PM, Craig wrote: CRM My suggestion is to implement this logic inside a bean that hides whether CRM or not you are really caching the data or not -- say a StoresBean CRM something like this: CRM public class StoresBean { CRM public ArrayList stores = null; CRM public synchronized Iterator getStores() { CRM if (stores == null) { CRM stores = new ArrayList(); CRM ... fill in the objects in this list ... CRM } CRM return (stores.iterator()); CRM } CRM } CRM That way, the relevant stuff will get loaded the first time and then CRM reused. RR Ok, you've started to clear some things up for me. I always RR thought thought that classes in my: myAppDir/WEB-INF/classes RR directory if they had static members they were shared across the RR entire application scope? This definitely is wrong though? (and RR it's only session scope?). RR In your above code, though, each user session would then end up RR loading a new list of stores. I don't really need that. I only RR need that list being loaded once and shared amongst all the RR sessions. CRM But your calling application doesn't know that -- all it needs to CRM do is grab StoresBean out of the session attributes (if this is user CRM specific) or context attributes (if this is global), and call getStores(). RR How would I grab this global attribute from a business layer RR object though? I guess that's where I'm getting confused. Say I RR have my Action class call a business object: RR BO.getStoresList() RR Well now I want the BO to return me a List of StoreBeans, but I RR only want that list populated ONE time and want all the sessions RR to share it.It looks like if I want all the sessions to share the information RR I have to pass servlet classes into my model layer? Am I wrong RR there? CRM If the StoresBean bean is in application scope (i.e. a servlet context CRM attribute), then getStores() will go load up the list the first time *any* CRM user requests it, then everyone will share. This makes sense if the data CRM is global to all users. You would want to create this bean as part of CRM your application startup, by either: CRM * In servlet 2.2 or later, create a servlet that is configured for CRM load-on-startup, and set it up in the init() method. RROk, I have set up some like this in the init() method of an RRIntializationServlet I call on startup: RRcontext.setAttribute( storeList, storeList ); CRM * In servlet 2.2 or later, subclass the ActionServlet class in Struts, CRM and override the init() method like this: CRM public void init() throws ServletException { CRM super.init(); CRM ... initialize context attributes here ... CRM } RR OK! Perfect this is exactly what I should do. Thank you. RR (I take it there weren't be any issues doing this to my RR controller which extends DispatchAction). RR Thanks Craig, RR Rick RR -- RR To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] RR For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- Rick mailto:[EMAIL PROTECTED] Sometimes you have to be careful when selecting a new name for yourself. For instance, let's say you have chosen the nickname 'Fly Head. Normally you would think that 'fly Head' would mean a person who has beautiful swept-back features, as if flying through the air. But think again. Couldn't it also mean 'having a head like a fly'? I'm afraid some people might actually think that. -Jack Handey -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]