I am new to ejbs and cdi. To my understanding a stateful ejb stores the data in the instance variables and destroys the stateful ejb after the request is finished.
I recently attended an interview where the interviewer asked me what kind of ejb would I use in an online shopping kind of application.
If I have to do it without ejbs, I create a HttpSession and then add the user interest in the session and then show him another page to continue or make the payment or exit.
If I want to accomplish the same using stateful ejbs, I dont understand why should I use stateful ejbs, what is its significance? Because once the request is completed the ejb is destroyed and the user interest/cart-details are destroyed.
Secondly what I am not able to understand about cdi is, suppose I am injecting the service class into my servlet, because injection happens only once there will be only one instance of the service class. When more than two requests come the instance variables of the stateful ejb get corrupted. So I guess when I am using stateful ejbs I have to use #RequestScoped annotation. Am I right?
Stateful session bean will allow you to store the same state as an http session. Few advantages over using http session that I can think of:
Scalability - Your SFSB can be deployed on another server and scale independently using remote interfaces
Non-web clients - You can use SFSB to maintain state for a non-web client where http session will not be available
The other benefits that come with using an EJB
To hold a reference to a stateful EJB in a servlet you should use #SessionScoped with #Inject as indicated in this answer
Related
I have a Java EE application using EJBs, and perform most of the functions through Stateless EJBs.
I have a requirement for all users to also have an active session, and I'm wondering what the best way of using the beans are.
Currently, I have a command line client which uses the stateless beans directly in addition to logging into the system with the stateful bean.
I'm wondering if I should have the client perform all functions through the stateful bean, that way no functions can be performed unless an active session exists.
This makes more sense to me personally.
I'm just not quite sure what design is 'right' or what is the better design.
If I continue to have the client use the stateless beans, then I'll have to have a way for those stateless beans to check if the client has an active session.
A session exists anyway even if you're only invoking stateless beans. The choice on whether to invoke a stateless or stateful bean should mater only whether you need to keep state between method invocations. Try injecting the SessionContext and notice that there will be a principal, even if it's anonymous.
If your requirement is an authenticated user, a stateless session bean is fine:
You can call SessionContext.getCallerPrincipal() in the EJB (for logging purposes etc.)
You can impose authorization declaratively (using the #RolesAllowed annotation on EJB methods)
so I don't see a reason to switch to stateful session beans. It might not be relevant, but a stateful session bean consumes resources on the server side, so there should be a compelling reason to do so.
A related question When to use Stateful session bean over Stateless session bean? received no answers up to today, and I consider no answer in this case to be an answer as well.
Coming from plain old DI of Spring I can't figure out how to choose scopes properly while writing with CDI.
In Spring all my services have singleton scope by default, which I suppose maps to application scope in CDI (or even #Singleton). I know for e.g. logged in user information I need to use Session scope and for e.g. form params I need request scope.
Say I have a bean that hides external service API calls. It is completely stateless. Should I put it as #Singleton or simply application scoped? Or let it be created on every request (possibly bad option).
Is this correct to inject everything everywhere? In Spring I create my data objects by new. Should I do the same in CDI or simply #Inject them?
Are you only using CDI? or a Java EE 6 container? If you have a stateless class that is used for service calls, then I would recommend using #Stateless, which is from the EJB spec (so you would need a Java EE 6 container) It isn't a singleton, but it doesn't get created on each request either. I believe it is more closely bound to the session, but since it is stateless, instances can be pooled and shared. If you are only dealing with CDI, I believe Singleton matches more directly to Spring's singleton, but I would recommend using ApplicationScoped because it provides a proxy which makes serialization of beans that use it easier.
#Service
#Scope("prototype")
public class CustomerService
{
......
}
Just add #Scope("prototype") annotation to your component.
Is there a reason you would need the bean to remember it's state? If you are using something like a web client, that is a better place to store state in say, session scoped managed beans (assuming jsf), or whatever equivalent for your case. On the back end server side your EJB's would be better kept as #stateless to keep overhead to a minimum and help with the 'keep it simple s..." paradigm. And in case this works, just declare #Stateless on your bean. Unless there is a reason to use a singleton, again it is better to use a stateless bean if you want to go with a Java EE container for your services.
Stateless beans are not really being recreated with every request. That is the purpose of the pool. The app server keeps a ready supply of stateless beans on hand, and if it gets busy, it will make more, and if it quiets down, it will empty some out.
I'm working on a Java webapp trying to combine the following technologies:
Java EE 6
CDI
JSF 2
EJB 3.1
Spring Security
I provide CDI-based backing beans (#ViewScoped, #Named) for my JSF pages.
I use #Stateless EJB beans for the actual work to be done.
I only need few session information like jSessionCookie (managed by container), internal username and some other internal IDs. Now, I wonder where to put this session information so that I can access it in the backing beans for JSF, but also provide it to the stateless EJBs? Should I use a #Stateful EJB session bean or should I create CDI-based POJO with #SessionScoped and #Named?
Are there any best practices?
For your particular use case, a stateful session bean would not be a good choice.
Do note that contrary to what people may claim, stateful session beans are surely not something you should generally avoid. However, they are for advanced use cases, for instance when dealing with JPA's extended persistence context.
The reason why stateful session beans would not work here, is that they are not automatically associated with the HTTP session, which seems to be your prime concern. You could add the #SessionScoped annotation to them, but then you could just as well use a regular managed bean. You would not use any of the particular features of a SFSB.
See alo:
Can I use EJB Stateless Bean with CDI to maintain user session?
Using a Stateful Session Bean to track an user's session
Calling a CDI session scoped producer method from an EJB stateless session bean
Contexts and Dependency Injection in Java EE 6
You can inject your stateless EJBs with a session scoped CDI bean, but you have to realize that within the same application your EJB bean would be dependent on the HTTP session then (something you sometimes want to avoid, e.g. if your bean has to be called from other contexts as well).
#Stateful EJB is something I'd try to stay away from. I believe behavior and state are things that should not be mixed.
I would also go for SJuan76's answer and use SessionScoped JSF backing bean.
Based on this post http://www.adam-bien.com/roller/abien/entry/ejb_3_1_killed_the I use in my app #Named #Stateless bean for communication with a database (injecting EntityManager here) and display information on a jsf page. It's great facilitation since Java EE 5, but I have one question.
Is it secure to use such beans for maintaining a user session (shopping cart etc)? I read a book about ejb 3.0 and I know that the same stateless bean could be used with many clients.
What's the best approach to use a managed bean with all ejb features (transactions, thread safety etc)? I mean any other way than managed bean + ejb interface with implementation + ejb injection as in Java EE 5?
I use GlassFish 3.1 WebProfile
Adding to the advice of duffymo; there are some additional considerations for using stateful session beans vs using the HTTP session.
The HTTP session basically has a map like structure. It's directly available to all threads (requests) that are part of the session. This makes manipulating several items a relatively unsafe action. It's possible to synchronize on the session itself, but this is a risky operation that can potentially dead-lock your entire application. The HTTP session does allow you to declare event listeners, which fire upon any kind of modification of the http session.
The Stateful session bean of course has a bean structure. It has a kind of auto synchronization feature, as only thread can be active in the bean at the same time. Via annotations you can declare if other threads wait (and if so, for how long) or immediately throw an exception in the face of concurrent access.
Where there is normally only one http session per user, a single user can make use of multiple stateful session beans at the same time. A particular advantage of stateful session beans is that they have a mechanism to passivate their state after some timeout, which can free up your server's memory (at the cost of disk space of course). Stateful session beans do not directly have the kind of event listeners that the http session does have.
I think that originally the "session" aspect of stateful session beans was to maintain a session with remote non-web clients (Swing, another AS, etc). This is much like the http session was created to maintain a session with remote web clients. Since a non-web client can request and hold on to multiple proxies for stateful session beans, the web analogy is actually more akin to that of the recently introduced conversation scope.
In the case of remote web clients talking to a server, where the server internally talks to a stateful session bean, the concepts greatly overlap. The remote web client only knows about the http session (via the JSESSIONID) and nothing about the stateful session bean's session. So if the http session was lost, you typically would not be able to connect the remote client with the specific stateful session bean again. The HTTP session in this case is thus always leading and you might as well store your shopping cart items inside a single (http) session scoped bean.
There is one specific case where stateful session beans come in handy for internal communication, and that's if you need JPA's extended persistence context. This can be used if e.g. locks on entities need to last between requests (which is possibly handy for a shopping cart if you have limited stock and don't want to confront the user with an "out of stock" message as soon as he actually checks out).
Stateless beans cannot maintain shopping carts or session; that's what "stateless" means.
You need either a stateful EJB or to do it in the web tier. Those are the only places where session is maintained.
I'm just getting started with JPA, creating stateless session beans from the JPA entities, then accessing the beans through a web service. While I have a lot of experience developing database backed web services "the old way", I have some questions about what's going on behind the scenes with this new "annotation driven approach".
What I see is, NetBeans sort of directs you to build applications in this manner though their wizards.
Create an Enterprise Application with EJB and Web Application modules.
Create Entity classes. I created mine from an existing database.
Create session beans from the entity class.
Create Web services from the session bean.
It all looks pretty simple, but what's going on behind the scenes? Specifically:
I see that the web service (created with the #WebService annotation) references my stateless session bean (using the #EJB reference).
What happens here? Does it just grab an instance of the EJB from the application server's EJB pool?
Nevermind. I was thinking of an instance where there was more than 1 table - meaning more than 1 type of Entity class and more than 1 type of EJB. I was looking at the web service and just seeing the #EJB reference and didn't understand who it was getting the bean type from that annotation. Just below that however, it the reference to the local bean interface - so that's that.
If there is more than 1 type of EJB deployed to the server, how does it know which one to grab?
The EJB is defined via the #Stateless and #Local annotations. The bean implementation references an EnityManager via the #PersistenceContext annotation.
Where is the jndi lookup to the database done (maybe in the persistence.xml file)?
Do all of the EJBs share a common EntityManager (assuming the EntityManager is thread safe)? If not, I know that the EnityManager utilizes a second level cache to help reduce trips to the database, are these caches somehow kept in sync?
I know this is a lot of questions, but they're all sort of related and there seem to be a lot of complicated concepts for something that's so easy to build through the wizards. I want to make sure I understand what's all going on here.
Thanks in advance!
What happens here? Does it just grab an instance of the EJB from the application server's EJB pool?
A JAX-WS web component endpoint (as opposed to a JAX-WS EJB endpoint) follows the typical servlet threading model, which means that typically there is one instance that is executed concurrently for each client. JAX-WS implementations are free to leverage pools of bean instances to handle a request in a fashion similar to stateless session EJB components. (source: Developing Applications for the JavaTM EE Platform FJ-310).
In all cases, it is fine to inject/look-up stateless beans because the container guarantees that the beans will always be thread safe. In affect, the container automatically serializes clients calls but uses instance pooling to make sure you still get concurrency benefits.
If there is more than 1 EJB deployed to the server, how does it know which one to grab?
Hmm... I didn't get this one. Can you clarify what you mean exactly? Why would there be any ambiguity?
Where is the jndi lookup to the database done (maybe in the persistence.xml file)?
In a Java EE environment, you specify your data source in a <jta-data-source> element in each persistence unit of the persistence.xml file (which can contain several persistence units) and the data source will be obtained by the EntityManager (only when needed, i.e. only if a data access is really needed).
Do all of the EJBs share a common EntityManager?
No. The EntityManager is a non-thread-safe object that should be used once, for a single business process, a single unit of work, and then discarded. In a Java EE environment using EJB 3, the default pattern is "entitymanager-per-request". A request from the client is send to the EJB 3 persistence layer, a new EntityManager is opened, and all database operations are executed in this unit of work. Once the work has been completed (and the response for the client has been prepared), the persistence context is flushed and closed, as well as the entity manager object. (source: Chapter 4. Transactions and Concurrency).