Is it safe to inject #Resource UserTransaction to EJB Singleton bean - java

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

Related

What is the default type of a Session Bean?

I was reading best practices related to JavaEE APIs and came across a suggestion to use #Stateless and #Path together to make thread safe. That prompted me to inquire that when we do not mention anything, what is the type of session bean? Is it by default Stateful?
There is no default type of a session bean.
A class only becomes a session bean by annotating it with #Stateless, #Stateful or #Singleton.

Looking up SessionContext in JBoss 7.2

For various reasons I need to perform a manual lookup of SessionContext. In JBoss5, the solution
InitialContext initialContext = new InitialContext();
SessionContext sessionContext = (SessionContext) initialContext.lookup("java:comp/EJBContext");
has served med well, but from JBoss 7 I instead get a
javax.naming.NameNotFoundException: EJBContext -- service jboss.naming.context.java.global.EJBContext
Has something changed in how context is looked up in JBoss 7.2, or is my deployment lacking anything vital? For reference, standard injection works fine, this is the only lookup that fails. Or am I doing something terribly wrong (besides performing a manual lookup of SessionContext)?
According to specification of Java EJB (this one is for EJB 3.2. but nothing changed about EJBContext from previous one, EJB 3.x), you can inject EJBContext into your components either using annotation #Resource or manually via lookup (section 11.15):
The container must make a component’s EJBContext interface available either through injection
using the Resource annotation or in JNDI under the name java:comp/EJBContext
Standard way of looking up for EJB resource is via EJBContext.lookup method but there is also JNDI way which is the only possibilities if you don't have already EJBContext:
Context initCtx = new InitialContext();
EJBContext ejbCtx = (EJBContext) initCtx.lookup("java:comp/EJBContext");
This is exactly what you did, so what is wrong? There are two things, which one I'm not sure about. First, with manually lookup it's sometime needed to assign resource to component with annotation at class level:
#Resource(name = "EJBContext", type = javax.ejb.EJBContext)
public class MyComponent {
...
}
but I'm not sure is it needed for EJBContext as well, I guess not. The second thing, more important and critical - according to specification once again:
EJBContext objects accessed through the naming environment are only valid within the bean
instance that performed the lookup.
this one is section 11.15.1, and the next one, section 11.15.2:
The Container Provider is responsible for providing an appropriate EJBContext object to the refer-
encing component. The object returned must be of the appropriate specific type for the bean requesting
injection or performing the lookup—that is, the Container Provider must return an instance of the SessionContext interface to referencing session beans and an instance of the MessageDrivenCon-
text interface to message-driven beans.
Those both mean that injection and lookup for EJBContext are only valid in Enterprise Java Beans, so those which are annotated with #MessageDriven, #Stateful, #Singleton or #Stateless (or described as EJBs in deployment descriptor file, also as EJB 2.x Specification). Maybe your component isn't valid EJB and it's why lookup isn't working? This is only suggestion of course.
There's one more possibilities to get EJBContext (more correctly SessionContext). Your component should implements SessionBean interface which has setSessionContext(SessionContext sessionContext) method. This method should be invoked by EJB container every time when component is used (injected somewhere, invoked by client or timeout, especially when it's created) and inside this method you should assign sessionContext parameter to bean's field.

Java EE 6: How to call Stateful Session Bean from Stateless Session Bean?

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...

Which type of beans are injectible?

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.

How is threadsafty guranteed with #PersistenceContext?

According to many examples it is possible to inject an EntityManager into #Stateless or #Singleton EJBs like this:
#Stateless // or #Singleton
public class MyRepository {
#PersistenceContext
private EntityManager em;
...
}
The EJB 3.1 Spec says that dependency injection is only performed at construction time, so that all callers of MyRepository would use the same instance of EntityManager. How does the EJB container ensure that the correct EntityManager instance is used?
My understanding is that a #Stateless bean will never be used by two clients concurrently; the container will simply create more instances of the same bean if it needs to serve multiple clients.
As for #Singleton beans, the spec says that by default they use Container Managed Concurrency, where the container uses method Locks and could reject clients with a timeout exception if the singleton is busy.
Edit: additionally, the #PersistentContext type is transaction-scoped by default (16.11.1.1 in the spec) so all entities managed by EntityManager are detached at the end of each transaction.

Categories

Resources