Should I use @EJB or @Inject
Asked Answered
S

9

168

I have found this question: 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?

Slotter answered 15/11, 2011 at 14:52 Comment(0)
E
198

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:
Inject @EJB bean based on conditions

Estebanesteem answered 15/11, 2011 at 15:8 Comment(2)
why does @EJB work for circular injection (one singleton bean and another bean needing a reference to each other)? (with reference to my answer below - i am not sure if i am doing the right thing by switching to @EJB)Runyon
because you're not injecting the implementation, but a proxy that interposes on the implementation. because of this, you get the advantages of "late binding" and other container features.Friederike
W
38

@Inject can inject any bean, while @EJB can only inject EJBs. You can use either to inject EJBs, but I'd prefer @Inject everywhere.

Wastrel answered 15/11, 2011 at 14:57 Comment(2)
What exactly makes the injection when we use @Inject? The JavaEE container? Can it inject POJO 's?Sniffle
with CDI it's the CDI container (bundled in the JavaEE container)Wastrel
R
16

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.

Runyon answered 12/5, 2013 at 8:7 Comment(4)
@MartijnBurger I don't have the code handy, nor a Java EE environment handy. Just create 2 Java classes and @Inject them into each other's public fields. If that works then my answer is wrong. If that does not work, then my answer is correct so far. Next change the @Inject to @EJB (and possibly annotate the classes themselves? I forget.). Then the cyclic mutual injection should work fine. That's why I switched from @Inject to @EJB. Hope this makes sense.Runyon
I created two pojo's and injected the pojo's into each other. Works without problems in my config (WildFly 8.2 = CDI 1.2)Pitchstone
Thanks @MartijnBurger, I'll confirm that, and in the meanwhile add a note of caution to my answer.Runyon
No exactly sure what you wanted to achieve, but this probably does exactly what you wanted and without a circular dependency. tomee.apache.org/examples-trunk/async-postconstruct/README.html. Also asynchronous CDI events could be a cleaner way to go (depending on the requirements).Corncrib
S
12

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?

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

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

Scottiescottish answered 4/10, 2012 at 21:17 Comment(2)
While this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. That way this answer would be valuable even now when the link is dead.Colleague
web.archive.org/web/20140812065624/http://www.seamframework.org/…Scottiescottish
P
5

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

Powerless answered 8/8, 2017 at 6:51 Comment(0)
L
0

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.

Lanner answered 12/6, 2016 at 19:49 Comment(0)
G
0

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.

Gladiator answered 17/5, 2022 at 8:49 Comment(0)
R
0

@Inject is a documented annotation, so IDEA knows how to process it and you can see a different colours in a code. @EJB - no.

Reconcilable answered 27/10, 2022 at 13:44 Comment(0)
H
-1

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.

Howlyn answered 23/9, 2021 at 18:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.