What is the difference between @Inject and @EJB
Asked Answered
B

3

39

I'm currently learning the new Java EE 6 component models and am confused with the latest dependency injection mechanism. So here are my questions:

1) What is the difference between @Inject and @EJB

2) If I have a simple POJO that contains another POJOs (which one of them is the DAO code), what would be the better choice: @Inject or @EJB?

Can I mix @Inject and @EJB?

An example would be:

  • ClassA implements InterfaceA and has an instance of ClassA_Adaptor

  • ClassA_Adaptor implements InterfaceAB and has an instance of ClassB

  • ClassB implements InterfaceB and has an instance of ClassB_Adaptor and an instance DAO_ClassB

  • ClassB_Adaptor implements InterfaceB and has an instance of ClassC

  • ClassC implements InterfaceBC and has an instance of WebService_ClassC

  • DAO_ClassB will use JPA 2.0 (@PersistenceContext)

I'd like to inject all of them including the DAO and the WebService.

3) Is it a bad approach to only use transactional for certain operations but not for all?

As an example: Some methods in DAO_ClassB are your typical query, while other methods are "write" methods. Is it bad to not wrap the "READ" methods with transaction?

To my understanding, the DAO_ClassB can be wrapped with transaction using @EJB (inject the DAO_ClassB and make all methods transactional). How can I control it?

Sorry if some of the questions are confusing because I know only bits and pieces of the Java EE 6 new component model.

Bandit answered 4/5, 2011 at 20:57 Comment(0)
N
31
  1. @EJB injects EJBs only, but @Inject can be used to inject POJOs rather than EJBs. However, @Inject requires that your archive be a BDA (contain beans.xml for EE 6, or implicitly in EE 7). @Inject also has additional CDI-specific capabilities (scopes, interceptors, etc.), but those capabilities incur extra overhead. Application servers have support for specifying @EJB bindings so that a deployer can choose the target EJB, but @Inject only allows the application developer to choose the target EJB (and it must exist in the application).

  2. If the target is not an EJB, then you must not use @EJB.

  3. It depends whether you're making multiple inter-related queries and then attempting to make business decisions. You need to understand isolation levels and take them into consideration, even for read-only operations.

Nicholasnichole answered 9/5, 2011 at 3:58 Comment(6)
Thank you for the answer. Would you mind to explain what BDA is?Bandit
Bean Deployment Archive. It's a JAR that contains a beans.xml.Nicholasnichole
What are the consequences of injecting a (local, same-archive) EJB using @Inject rather than @EJB?Accessary
The @Inject version will respect the scope of the EJB. For example, using @EJB to inject an SFSB into a servlet makes no sense because only one SFSB will exist for every request. Using @Inject to inject a @SessionScoped SFSB into a servlet means you have a CDI proxy that creates a new SFSB as needed for each session.Nicholasnichole
If you inject an SLSB with @Inject the EJB container will still control the bean lifecycle?Slaty
Yes, the CDI container knows whether a type is an EJB interface, so it will still coordinate with the EJB container to obtain an EJB proxy, which allows the EJB container to control the actual bean lifecycle, and then the CDI container will wrap the EJB proxy with a CDI proxy as needed (e.g., contextual proxy is meaningless for a stateless bean but meaningful for a stateful bean).Nicholasnichole
F
13

From Adam Biens Weblog:

You can use both annotations to inject EJBs. Start with @Inject and if you encounter any problems, switch to @EJB.

@Inject does not have any methods / attributes--it is just a plain annotation:


@Target(value = {ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface Inject {
}

On the other hand, the @EJB annotation allows you to pass additional information, which could be useful to reference remote EJBs, or EJBs which cannot be simple injected in the "Convention over Configuration" style:

@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface EJB {

    public String name() default "";

    public String beanName() default "";

    public Class beanInterface() default Object.class;

    public String mappedName() default "";
}
Flirtatious answered 6/5, 2014 at 11:11 Comment(3)
Voted down for copying answer verbatim from this blog adam-bien.com/roller/abien/entry/inject_vs_ejb without giving credit.Annapurna
Still this I think this is the best answer. I added a reference to the original post in the anser.Ge
Dead link now :(Anticipatory
A
6
  1. @Inject is more general than EJB and is part of CDI specification. So if you want to use @Inject, you need an implementation of it in your server.

  2. For POJOs (not EJBs) you have to use @Inject.

Alveta answered 9/5, 2011 at 5:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.