One typical example of using a Stateful Session Bean is through a ShoppingCart example. We create a bean instance of the ShoppingCart class, then store this instance within a HttpSession.
However, the same can be achieved easily with the ShoppingCart class being a normal Java class (or a stateless session bean). A request of adding a product comes in, we create a cart object, then put that cart object inside a HttpSession.
So, I don't see the point of using a stateful session bean ShoppingCart here. And in general, a stateful session bean doesn't seem to play any significant roles.
I would rephrase your question:
Why should I use mechanism for automatic session based bean management (maintaining one instance per session, persisting inside session) if I can implement it myself?
Yes, you can implement it yourself and it would be pretty simple. However you can just use Java EE mechanisms for that.
Related
I have an ASP.NET 5 app using RavenDB, and I'm trying to create an attribute that will create a "Changeset" document with the keys of all the documents that were stored by the action.
For that purpose, I created an ActionFilterAttribute instantiated via ServiceFilterAttribute, which is registered as Scoped, that sets a flag on another Scoped component, let's call it ChangesetAccessor, which holds the list of changes.
The IDocumentStore is obviously a Singleton, and the listener (IDocumentStoreListener implementation) is manually instantiated. It needs access to the current ChangesetAccessor, so I thought giving it a reference to the IServiceProvider so it can call GetService<ChangesetAccessor> as needed would be enough, but it is receiving a different instance.
How can I get the ChangesetAccessor for the "current request" from my listener?
You can actually access RequestServices off of the HttpContext to get scoped instances. It's kind of backwards, and really will depend on Microsoft.AspNet to do it, but it will work for your situation; interestingly, IHttpContextAccessor is a singleton, too, though it gives you a scoped value.
// injected:
IHttpContextAccessor httpContextAccessor;
// in your method:
httpContextAccessor.HttpContext.RequestServices.GetService<ChangesetAccessor>()
I am starting a new project with JavaEE 7 and declared a Sessionscoped bean to maintain the web logged user information in session.
The UserSessionBean, as I named it, is intended to be lightweight - trying to avoid lots of data to be kept in the session by Weld. But in some cases I need to get all user information, so added a getUser() method which must query and retrieve a UserEntity from JPA. In order for the method to do its job, I need to #Inject other resources onto the UserSessionBean.
My question is: These dependant resources will be kept and serialised within the UserSessionBean by Weld until the context is destroyed?
The weld documentation says this:
An instance of a dependent bean is never shared between different
clients or different injection points. It is strictly a dependent
object of some other object. It is instantiated when the object it
belongs to is created, and destroyed when the object it belongs to is
destroyed.
That makes me think the all SessionBean tree is kept by weld during session life, but how can I keep a lightweight SessionBean and use injected CDI resources on it?
Since what you're injecting are also CDI beans, it is not the beans themselves that get serialised, but their lightweight proxies. Upon deserialisation, the proxies dynamically resolve the correct beans for whatever scope they are. See section 5.4 Client Proxies of the CDI1.0 spec. Hence, your bean is as lightweight as possible.
Looking at some of the MVC examples online, I've see that typically in a controller the DbContext variable is declared as a private member variable (i.e. global) and accessible to all the methods.
But, I recently came across an article on ASP.NET Identity, and noticed in the controller, the DbContext is declared within each method (that requires it).
Is there a security benefit to this approach? Perhaps limit the lifespan of the security object(s) for better overall security?!?!
If not, then I see the first approach being more efficient, where the database context is instantiated upon the controller loading.
Below is all I could find about DbContext, but nothing to really answer my question.
DbContext declaration - Framework 4.1 - MVC 3.0
MVC, DbContext and Multithreading
On every request, a new instance of the controller is constructed. Therefore, for all intents and purposes, it does not really matter whether the dbcontext is instantiated in the constructor vs encapsulated in any given method.
Aside from a style choice, reasons to declare and contain a dbcontext in a given method is that:
Methods that do not need it will not instantiate the context, eliminating the overhead (if there is any). This can also be accomplished using a lazy initialization pattern.
The context is disposed of immediately as soon as a method is done with it, rather than at the end of the request. Generally this should not be a concern though; usually if users are waiting around for longer than a few seconds you have a bigger problem.
Different methods use different contexts.
Among others, some reasons to declare a single context and instantiate it once:
You have only one place that instantiates a context rather than many. In a typical application, most pages will need some information from the database anyway.
Methods that call other methods will not each hold on to their own instance of a context object.
You can create a base controller class that by default creates a dbcontext object, allowing you to be DRY in all inherited controllers.
Answer from #Ic. is pretty good. I wanted to add that if you need to pass information from your Request into your DbContext constructor then you need to create the instance of your DbContext inside your action methods. The reason is the Request object will be null till the control enters your action method.
More information: I had a need to build connection string dynamically depending on the location of the user. I saved the location as a cookie that I accessed through Request object. I had a valid Request inside the action method but it was null inside the constructor or at the class level properties of the controller.
Old code creates a #SessionScoped #ManagedBean (namely UserSession) at the first request in a ServletFilter and puts it in the HttpSession (if not already there).
Now what happens when some EL expression tries to access that ManagedBean the first time? I expected a second instance of UserSession (one created manually and one from JSF). So I instrumented the constructor, #PostConstruct and #PreDestroy with a few logging statements. Now it seems JSF never creates the UserSession - only the constructor is called.
Is this possible? Can JSF reuse that bean from HttpSession? Is it legit to put #SessionScoped beans in HttpSession?
Your observation is correct. Under JSF's covers, JSF itself also stores session scoped managed beans as an attribute of the HttpSession. So if it's already present, it will just be reused, regardless of the way how it has ended up in there.
Whether that's good or bad depends on the concrete functional requirement. Given your astonishment, I'd guess that it's bad and that you need to revise either the approach or the functional requirement. Perhaps you need a secondary (session scoped?) managed bean which injects the particular session attribute by #ManagedProperty.
Couple of questions on setting managed bean using CDI.
1. If a session bean is Injected into another using #Inject annotation, how to replace the entire session Bean?
2. In CDI, Is it possible to define Injection to only inject (not to outject).
If a session bean is Injected into another using #Inject annotation, how to replace the entire session Bean?
You don't. This requirement can mean only 1 thing: the session scope is the wrong scope for the bean in question. Perhaps you're looking for the conversation scope instead.
If you really need to, you can always add some clear() method which clears the state (thus, all of its properties) of the session scoped bean, but this is still fishy. Just choose the right scope from the beginning on.