I like to know what is the main difference between EJB #EJB and #Resource annotation? In which case we have to go for #EJB and #resource
Specification states, regarding #EJB:
The Bean Provider uses the EJB annotation to annotate a field or setter
property method of the bean class as a target for the injection of an
EJB reference. The reference may be to a session bean’s business
interface or to the local home interface or remote home interface of a
session bean or entity bean.
regarding #Resource(section 16.2.2):
A field or method of a bean class may be annotated to request that an
entry from the bean’s environment be injected. Any of the types of
resources or other environment entries described in this chapter may
be injected.
Mentioned entries include: EJB reference, web service reference, resource manager connection factory reference, message destination reference, unit reference, persistence context reference, UserTransaction, CORBA ORB object, TimerService, EJBContext object
Related
We migrated from Jboss EAP 5 to EAP 6 in our development environment.
I now see the following in my JBOSS logs. I am trying to understand how this binding happens. I have read JBOSS docs on JNDI namespace binding. Still I am not totally clear how it works. Here is my log.
java:global/customerCare/services/UserDaoImpl!com.example.services.UserDao
java:app/services/UserDaoImpl!com.example.services.UserDao
java:module/UserDaoImpl!com.services.UserDao
java:global/customerCare/services/UserDaoImpl
java:app/services/UserDaoImpl
java:module/UserDaoImpl
Here are my EJBs
#Local
public interface UserDao {
public static final String JNDI_NAME = "java:global/customCare/services/UserDaoImpl";
//interface methods here
}
#Stateless
public class UserDaoImpl implements UserDao {
// implement methods
}
My doubts are:
I explicitly had JNDI binding to be java:global/customCare/services/UserDaoImpl in my UserDao interface.
Then why do I see I binding for others such as app and module.
what is the difference between app and module? when would binding to these components be needed? some example here to illustrate will be very helpful
The last three lines of log show binding to UserDaoImpl. Is it something that JBoss does without I ask it to bind? ( I set only UserDao but not UserDaoImpl for JNDI binding).
I am a bit illiterate on JNDI Namespace binding. Reading docs helped me but not to great extent.
Thanks
I can answer doubt 2:
All the names are the same thing but with different contexts.
The global name is a full JNDI context that is used to bind globally, ie. from a client or from another EAR file
The module name can be used to bind within the same application, ie different EJBs within the same EAR
The local name is used to bind locally, ie within an jar or war.
It is slightly more efficient to use the shorter names to bind locally than specifying a full global name each time.
From what I have seen JBoss EAP 6 will always list the three / six names for every enterprise bean during deployment. It is intended to help you as a developer identify the JNDI name(s) for the bean.
I put together a small sample app here: https://github.com/lakamsani/cdi-nested
MyResource is a JAX-RS service into MyService is #Injected
MyDao is in-turn #Injected into MyService. When I run it (in TomEE 1.6.0.1), MyDao is null inside the MyService instance injected to MyResource. What do I need to do to make it work or is there another way of doing this (short of explicitly instantiating objects).
I think what you are seeing is a proxy instance of MyService being injected into MyResource. Once you call a method on MyService, then a real instance is obtained from the correct context and it is in turn injected with MyDao.
If you really need a "real" instance of MyService when it is injected into MyResource, you may be able to make MyService a dependent scoped cdi bean and not a #Stateless EJB.
I may be misunderstanding why you need MyDao to be injected into MyService before any business methods are called.
I am using Glassfish server. It seems that the #LocalBean is getting initialized at server startup. For other beans they are correctly initialized on look up. Is this the correct behaviour for LocalBean ?
There is no rule saying that #LocalBean should be eagerly initialized and others should not. It's left to the container provider to decide when particular bean should be initialized.
The only case you have control over when bean is initialized is to use #Singleton EJB with #Startup annotation. This will force container provider to create an instance of the singleton bean during server startup. This is a good place to put your initialization logic within.
The behavior you've observed might be correct in case of Glassfish but I would not relay on it because other container providers might choose different approach.
I have two ear applications (EJB 3.0) deployed on Jboss 5.1. SLSB from application A calls remote SLSB from application B via #EJB annotation.
Everything works fine, until I redeploy application B. Then the bean from A application tries to call the one from B and its reference turns to be null.
I suppose that SLSBs are pooled and references are injected on creation time, and after redeployment those proxies are not refreshed somehow.
How can I cope with that? Is it ok to put an interceptor on that bean and check if all annotated references are not null?
If the application is redeployed/undeployed or there is network failure, the proxy objects are invalidated.
You can use ServiceLocator pattern for caching the references of the remote objects. You can remove & again re-create them with JNDI lookup in case of failure.
Else, instead of using #EJB to inject remote bean, you have to manually lookup each time which is resource consuming, but former is much better approach.
I'm working with EJBs...I do the following and I don't know why the injected EntityManager is not working as one might expect.
EJB1 calls a method on EJB2 that writes to the DB.
when EJB2 returns EJB1 sends a message to a MDB.
MDB calls EJB3 that reads the DB and does some work.
My problem is that the EntityManager injected in all 3 EJBs with #PersistenceContext is not working properly. Calling persist() in EJB2 is not being reflected on the EntityManager injected in EJB3.
What might be wrong?
Hope I made my problem clear enough.
now working with Container managed transactions.
My problem is that the EntityManager injected in all 3 EJBs with #PersistenceContext is not working properly. Calling persist() in EJB2 is not being reflected on the EntityManager injected in EJB3.
In a Java EE environment, the common case is to use a Transaction-Scoped Container-Managed entity manager. And with such an entity manager, the persistence context propagates as the JTA transaction propagates.
In your case, I suspect you're using a REQUIRES_NEW transaction attribute for the method of EJB3. So:
when invoking EJB3#bar(), the container will suspend the transaction started for EJB2#foo() and start a new transaction
when invoking the entity manager from EJB3#bar(), a new persistence context will be created.
since the transaction started for EJB2#foo() has not yet committed, changes aren't "visible" to the new persistence context.
PS: Are you really creating new threads? If yes, little reminder: this is forbidden by the EJB spec.