Should I use @EJB or @Inject
JavaJakarta EeEjbCdiJava Problem Overview
I have found this question: https://stackoverflow.com/questions/5889767/what-is-the-difference-between-inject-and-ejb but I did not get any wiser. I have not done Java EE before nor do I have experience with dependency injection so I do not understand what I should use?
Is @EJB
an old way of injecting? Is the injection done by the EJB container when using this annotation while using @Inject
use the new CDI framework? Is that the difference and should I be using @Inject
instead of @EJB
if this is the case?
Java Solutions
Solution 1 - Java
The @EJB
is used to inject EJB's only and is available for quite some time now. @Inject
can inject any managed bean and is a part of the new CDI specification (since Java EE 6).
In simple cases you can simply change @EJB
to @Inject
. In more advanced cases (e.g. when you heavily depend on @EJB
's attributes like beanName
, lookup
or beanInterface
) than in order to use @Inject
you would need to define a @Producer
field or method.
These resources might be helpful to understand the differences between @EJB
and @Produces
and how to get the best of them:
Antonio Goncalves' blog:
CDI Part I
CDI Part II
CDI Part III
JBoss Weld documentation:
CDI and the Java EE ecosystem
StackOverflow:
https://stackoverflow.com/questions/7920123/inject-ejb-bean-based-on-conditions/7923159#7923159
Solution 2 - Java
@Inject
can inject any bean, while @EJB
can only inject EJBs. You can use either to inject EJBs, but I'd prefer @Inject
everywhere.
Solution 3 - Java
Update: This answer may be incorrect or out of date. Please see comments for details.
I switched from @Inject
to @EJB
because @EJB
allows circular injection whereas @Inject
pukes on it.
Details: I needed @PostConstruct
to call an @Asynchronous
method but it would do so synchronously. The only way to make the asynchronous call was to have the original call a method of another bean and have it call back the method of the original bean. To do this each bean needed a reference to the other -- thus circular. @Inject
failed for this task whereas @EJB
worked.
Solution 4 - Java
Here is a good discussion on the topic. Gavin King recommends @Inject over @EJB for non remote EJBs.
http://www.seamframework.org/107780.lace
or
https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace
> Re: Injecting with @EJB or @Inject? > > 26. Nov 2009, 20:48 America/New_York | Link Gavin King > > That error is very strange, since EJB local references should always > be serializable. Bug in glassfish, perhaps? > > Basically, @Inject is always better, since: > > it is more typesafe, > it supports @Alternatives, and > it is aware of the scope of the injected object. > > I recommend against the use of @EJB except for declaring references to > remote EJBs.
and
> Re: Injecting with @EJB or @Inject? > > 29. Nov 2009, 17:42 America/New_York | Link Gavin King > > > Does it mean @EJB better with remote EJBs? > > For a remote EJB, we can't declare metadata like qualifiers, > @Alternative, etc, on the bean class, since the client simply isn't > going to have access to that metadata. Furthermore, some additional > metadata must be specified that we don't need for the local case > (global JNDI name of whatever). So all that stuff needs to go > somewhere else: namely the @Produces declaration.
Solution 5 - Java
It may also be usefull to understand the difference in term of Session Bean Identity when using @EJB and @Inject.
According to the specifications the following code will always be true
:
@EJB Cart cart1;
@EJB Cart cart2;
… if (cart1.equals(cart2)) { // this test must return true ...}
Using @Inject instead of @EJB there is not the same.
see also stateless session beans identity for further info
Solution 6 - Java
Injection already existed in Java EE 5 with the @Resource, @PersistentUnit or @EJB annotations, for example. But it was limited to certain resources (datasource, EJB . . .) and into certain components (Servlets, EJBs, JSF backing bean . . .). With CDI you can inject nearly anything anywhere thanks to the @Inject annotation.
Solution 7 - Java
when you heavily depend on @EJB's attributes like beanName, lookup or beanInterface) than in order to use @Inject you would need to define a @Producer field or method.
Solution 8 - Java
use @EBJ with EJB's. This is for creating a separated business logic layer that is independent of the types of interfaces (Tiered Applications).
This (used correctly) allows the business logic to be modified and deployed separately from the (multiple) user-interface applications without loss of availability.