• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

how to maintain state

 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can someone please explain how it is possible to maintain state using a prototype bean? Would you store it as a session variable? I know its not recommended to maintain state using a singleton, but it is possible right? For example if we have some login functionality then between login and logout we can make use of a singleton bean (lets call it user). At the point of login we will populate the user object as required (e.g. based on provided username go to the database and get associated data and populate the user object with this data). Then at the point of logout we can set the object back to its initial state e.g. set user object variables to null. Would this approach work or am I talking gibberish!!!
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In general, in webapps state is maintained by storing things in the session or in the database - storing state in the objects that service the request themselves causes problems because these objects are shared by multiple users / threads of the webapp.
 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So do all users share the same instance of a singleton bean??? If thats the case I will need to synchronise all my singleton class methods right?
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How would you keep all users in a singleton? Why aren't you using a user-per-user? Seems kind of common-sense.
 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry but I am having considerable difficulty understanding spring beans in the context of a web app. Say I have a web app and in my appContext file I have a singleton bean (id=bean1). When the container is instantiated what I want to know is do all users of the application share the same object instance of bean1? If this is the case then its clear that it is not correct to maintain a user via a singleton.

However if user1 has his own object instance of bean1 and user2 has his own instance of bean1 then the solution i specified in my first post in this thread is feasible right?
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If it's a prototype bean, then sure, you could store it in session. If it's a singleton bean then it's completely unsuitable for tracking users.
 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If I use a prototype bean then i will be injecting this into a singleton in which case I will have to perform method injection. I think it would be alot easier if at login time I just hard code the initialisation of the user object in the singleton:

and then just add user to the session. Then on logout I will do:
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What singleton are you talking about?
 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After the user has successfully logged in (using j_Security_check) my struts2 action class (which I have configured as a spring managed bean) will be executed. From here I will call my dao which based on the provided username will get the user object from the database (i'm using hib annotations for mapping). I will then send this user object back to my action class and store it on the session.

I have specified my action class as a request scope bean not a singleton. Sorry.

Also now I can see that at registration time there is an opportunity to use a prototype User bean but this is not required at login
 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
vik ar wrote:If I use a prototype bean then i will be injecting this into a singleton in which case I will have to perform method injection. I think it would be alot easier if at login time I just hard code the initialisation of the user object in the singleton:

and then just add user to the session. Then on logout I will do:


Can someone please confirm the methodology I have specified in this post is correct. So each time a user logs on a new user object will be created for him/her. cheers
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Struts 2 actions should probably be declared as "prototype" scope, but in practice it may not make a difference--I've just never tried it.
 
Nathan Pruett
Bartender
Posts: 4121
IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, your example of creating the User and storing it in the session is the way it's usually done with model objects in Spring. Model objects aren't a Spring controlled bean at all - prototype or session - but they are used by these beans.

"User" is a model, so you'd create a "User" class that has all the fields you're interested in - like "loginName", "displayName" - maybe "email", "role", etc. "User" might be a hibernate and/or JPA, etc. annotated/mapped class to handle mapping it to database tables - or may not if you're just using JDBC. This class would not appear in the Spring configuration as a bean - because Spring isn't handling creation of it - instances get created during program use by the DAO layer (and possibly the web layer - though probably not in this instance).

You would create a "UserDAO" class to handle data access - this could extend SimpleJdbcDaoSupport if you're using JDBC, HibernateDaoSupport if you're using Hibernate, extend nothing but have an injected EntityManagerFactory if you're using JPA, etc. This class handles interactions with the database - so you have methods to find existing "User" instances in the database, create new "User" instances in the database, delete "User" instances from the database, update a "User" instance in the database, etc. This class will create the actual "User" objects - if you're using JDBC, you'll probably have to manually construct and populate the instances yourself in the code, if you're using an ORM tool, it will probably handle actual object creation and population. This class will be in the Spring configuration - as a Singleton.

Above the DAO is the Service layer - this layer has what are usually termed "Business methods" in it - so you might create a "UserService" class and add methods like "login", "logout", "checkPermission", etc. This class will also be in the Spring configuration as a Singleton. This class will use the DAO layer to do any database operations it needs, so you'll need to inject a dependency on the "UserDAO".

Above the Service layer is the Web layer or Presentation layer - this layer deals with interacting with the user - dealing with navigation around the web app, converting String input from web forms into object representations needed by the code, etc. This layer is a mix of various Controller classes (mapped in the Spring configuration as Singletons) and JSPs the Controllers use as Views. In some cases your Web layer Controllers may also create instances of your model classes - probably not in the case of User, you'll just take the login and password as Strings and pass them to the service layers "login" method to get back a User object - but in cases it makes sense for a new object to be constructed when a form is submitted. Depending on the controller class you use, this may happen automatically or you may have to call the constructor manually in your code.
 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
David Newton wrote:Struts 2 actions should probably be declared as "prototype" scope, but in practice it may not make a difference--I've just never tried it.

Can you please elaborate on why you think a action class should be declared as prototype scope as opposed to request. I chose request scope based on what I read here. However I agree that I dont think there will be any difference- as each request comes in a new instance of the action class will be used (I think...)
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because Struts 2 already handles action instantiation per-request.
 
vik ar
Ranch Hand
Posts: 104
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also here prototype is being used. I will make the change. Cheers
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic