With the concept of CDI in EJB3.X, you can inject the beans or entities.
What i want to know is: which types of beans you can inject.
Session Bean in Entity? Entity in MDB, etc???
How can I find a table that show the possiblities what i can do/inject in CDI concept.
Take a look at DZone Ref Card can be found here.
Quick Look:
Session Beans can be injected into Session Beans, MDBs can be injected in SessionBean, Entities can be injected in SessionBean.
Stateful beans shouldn't be injected in stateless beans.
Related
I have been trying to understand spring beans. As per my understanding, by default all beans are singleton and a singleton bean with lazy-init property set to true is created when it is first requested and singleton bean with lazy-init property set to false is created when the application context is created.
So, in an application, when a user request comes in ( where each request is a separate thread), do all these threads share the same singleton beans when requested within the program/class?
Yes, if the bean is created with default scope, the bean is shared across threads. However, another scope can be used to achieve the behaviour you mentioned.
See: https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html?
Yes, by default (scope == 'singleton'), all threads will share the same singleton bean. There are two other bean scopes, session and request, that may be what you're looking for. The request scope creates a bean instance for a single HTTP request while session scope maintains a unique bean for each HTTP Session.
For a list and description of all of the Spring bean scopes, check out: Spring bean scopes
The best way to understand this is to understand how #Autowired annotation works.
Or in other words to understand "Spring Dependency Injection".
You said, "
by default all beans are singleton
We use #Autowired when injecting one layer into another between two layers.
If exemplify: Suppose, I want to inject UserService UserController. UserService is a Singleton bean. Creates an instance from UserService and Stores its cache. When we want to inject this service with #Autowired annotation. This annotation brings the UserService stored in the cache.
In this way, Even if we do this inject operation in many classes.#Autowired inject an instance of UserService with singleton bean instead of dealing with one UserService at each time. It saves us a big burden.
This is the fundamental working logic of Spring Singleton Bean.
Also, Spring Ioc Container manages this whole process.
In spring the classes annotated with #Controller, #Service, #Repository, #Component act as Spring beans and will be instantiated by Spring container in singleton (Default scope).
Here the model beans are not annotated with any stereo type annotations.
My question here is whether the model beans are singleton or not i.e., if they come under Spring container.
If it is true then, how has the concurrency issue been handled?
Model attributes, ex. from #ModelAttribute annotated parameters, are not beans. They are not managed by the BeanFactory / ApplicationContext. They are created by the DispatcherServlet's MVC stack and provided to you. There's no concurrency issue (unless you create one) because a Servlet container handles each request in a single thread.
Q1:
I am writing an EJB Singleton bean that use BMT so I need to use UserTransaction in my bean. I was wondering that IS IT SAFE to inject #Resource UserTransaction to my EJB singleton bean. I don't know whether container will inject a Proxy of UserTransaction or NOT. Can someone give me some ideas? Thank you!
Q2:
What are difference between #Resource UserTransaction and sessionContext.getUserTransaction(). Are they equivalent?
I was wondering that IS IT SAFE to inject #Resource UserTransaction to my EJB singleton bean.
A Singleton session bean is one of the three beans defined in the ejb3.1 specification: Stateless, Stateful and Singleton.
Therefore, with Singleton, the Container must follow the same contract as other session beans.
The contract says:
4.3.3 The SessionContext Interface.
If the bean specifies a dependency on the SessionContext interface.., the container must provide the session
bean instance with a SessionContext. This gives the session bean instance access to the instance’s context maintained by the container.
.
What are difference between #Resource UserTransaction and sessionContext.getUserTransaction(). Are they equivalent?
Yes, they are. This what the specification says:
4.3.2 Dependency Injection.
Under the EJB 3.1 API, the bean class may acquire the SessionContext interface through dependency injection without having to implement the SessionBean interface. In this case,the Resource annotation (or resource-env-ref deployment descriptor element) is used to denote the bean’s dependency on the SessionContext.
Maybe your doubts comes from the fact that the same Singleton instance can be shared by several simultaneous threads,
which will share the same SessionContext instance. However. this shouldn't be a problem.
I use the conditional form because I have not tried it, but beyond the thread-safe related topic that can arise, take a look to the table on page 117
where explicitly is indicated that the use of UserTransaction method must be supported
Table 3
Operations Allowed in the Methods of a Singleton Session Bean:
Bean-managed transaction demarcation:
SessionContext methods: UserTransaction methods
I have a Stateful Session Bean (SFSB) which acts as authentication module. In the SFSB I store the current user that is logged in. Moreover I have some facades (which are Stateless Session Beans (SLSB)) that handles the JPA/SQL stuff for my entities. In order to check the access permissions of the current user, I try to call the SFSB out of the SLSB. But the current user field is always "null" when called from SLSB. When calling the SFSB directly, the current user field is set correctly... For calling I use the #EJB annotation.
Any ideas what the problem might be? Is that somehow a context problem? Is it generally possible to call a SFSB from SLSB preserving it's state?
Many thanks in advance!
You shouldn't call a stateful session bean from a stateless session bean.
Here is some reading: JEE6 Tutorial - Session Beans
Stateless beans don't know anything about your session. Any time you call it, it is stateless. Then it calls a stateful session bean. No surprise it doesn't have any context relating to the state of the client's session because it is called from stateless object.
I don't know if it will work, but you possibly could try to get the context by doing a JNDI lookup instead of DI using the #EJB notation. Something like this in the stateless ejb might work. You'll probably have to play with it and I can't guarantee anything. It should get the context of the client calling the stateless ejb. The client will need to have session context/scope or forget it.
#Resource SessionContext sessionContext;
MyStatefulBean msb = (MyStatefulBean)sessionContext.lookup("ejb/MyStatefulBean");
msb.doSomething(fubar);
It is better to call the stateful session bean from a client that has a session scope or from another stateful ejb. Stateless and stateful have different reasons for being.
You should not inject a stateful EJB into a stateless EJB. This can have very unpredicatable consequences, because lifecycle of a stateful EJB is started when injected and managed by owning bean. In the worst case, stateless EJB can be reused by application server for different users, which would then access the same stateful EJB. In your case, a user would be identified as a different user.
Most probably you want to associate a stateful EJB with current HTTP session, which is not done automatically as many people suppose. For more details read section named EJB 3 Is Not Contextual here: Contexts and Dependency Injection article
In order to associate a stateful EJB with the session, you need to inject stateful EJB into session scoped CDI bean, which can be injected freely into a stateless bean - actually only a stub is injected and session scoped bean (together with the stateful EJB) is created for every new session.
Maybe even better approach is to extract interface of the stateful bean, and use a CDI producer to create a session scoped implementation of the sateful bean. This way you can also handle the case, when a stateful EJB is automatically removed on an exception in the EJB. In such case, you may want to recreate the EJB within the same session.
If you inject the stateful session bean inside stateless bean by look-up also does not work because new instance will be created for stateful bean so it does not hold any values like logged user information and etc...
I have two kinds of backing beans in my JSF application:
Managed Beans (#ManagedBean(name="bean"))
Entity Beans (#Entity)
Which of them should be scoped (request/session/view/application/no)?
I'm having all of my managed beans scoped and entity beans not now (I had also entity beans scoped in the past and it seems to be the same as without scope). And in addition "not" could mean, that entity beans are request scoped.
Thanks for the explanation :)
The entity beans doesn't need to have a JSF managed bean scope assigned. They are supposed to be assigned as a property of a JSF managed bean. So basically, they will get the same scope as the JSF managed bean where it is been declared as a property. The JSF managed bean scope annotations works only in a #ManagedBean class. The entity beans are also not necessarily to be categorized as "backing beans". They are more "value objects".
You can see it as a further division of the "V" of the complete JSF MVC picture in another mini-MVC: the JSF managed bean is the controller, the Entity is the model and the XHTML file is the view.
See also:
What components are MVC in JSF MVC framework?
I would say your Managed Beans should be scoped .
and not the entity beans,
Thats assuming that entity beans are pojhos and all the operations are in
managed Bean.
I am answering this wrt JSF v 1.1
Hope this helps.