Ejb 3.1 @Localbean VS No Annotation

EJB 3.1 @LocalBean vs no annotation

The rules are (from memory):

  1. Bean has a @LocalBean annotation -> bean has a no-interface view
  2. Bean has a @Local annotation -> bean has a local view
  3. Bean has a @Remote annotation -> bean has a remote view
  4. Bean has no view annotations, but directly implements an interface which has a @Local annotation -> bean has a local view
  5. Bean has no view annotations, but directly implements an interface which has a @Remote annotation -> bean has a remote view
  6. Bean has no view annotations, but directly implements an interface which has no view annotations -> bean has a local view
  7. Bean has no view annotations, and implements no interfaces -> bean has a no-interface view

So, using @LocalBean and using no annotation at all are both ways of getting a no-interface view. If you just want a no-interface view, then the simplest thing is not to annotate. Provided you're not also implementing any interfaces.

Part of the reason @LocalBean exists to add a no-interface view to a bean which also has an interface view. I imagine the scenario uppermost in the spec authors' minds was one where you have a bean like:

@Stateless
public class UserPreferences {
public String getPreference(String preferenceName);
public Map<String, String> getPreferences();
}

Where you would want to expose both methods locally, but only the coarser-grained getPreferences() remotely. You can do that by declaring a remote interface with just that method, then just slapping @LocalBean on the bean class. Without it, you'd have to write a pointless local interface just to expose both methods locally.

Or, to look at it another way, the @LocalBean exists because there is such a thing as a no-interface view, and the no-annotation option exists as a handy shortcut.

EJB: exposes a local vs implement local business interface

In case that bean is implementing a local interface, the interface can be packaged in different module and this module can be later imported into the client application, thus hiding the implementation. On the other hand, no-interface view means that client would need to have dependency on the implementation which is less flexible solution.

So generally, you can safely use no-interface view when bean will interact only within your service (let's say some DAO helper class) and use bean with local interfaces it there is ever going to be used on the client side.

Nice explanation about all views is here.

EJB 3.1 - Using @EJB inside an EJB - is it possible?

Yes, it's possible.

The @LocalBean annotation, enables an EJB to expose a no-interface client view, so that you won't need to define a Local interface.

On the other hand, the @Local annotation defines a bean's local client interface.

Choose one of the above configuration options not both.

If you choose to use the @LocalBean annotation, drop the @Local annotation, remove the implements keyword and inject the bean class name with the @EJB annotation.

If you choose to use the @Local annotation, drop both @Local and @LocalBean annotations and inject the bean with the @EJB annotation using the interface name.

Is it possible to inject EJB implementation and not its interface using CDI?

Yes you can, but as EJB inject the business view the only business view you are exposing is the @Local view which is the default when you implement an interface (IBean in your case is a local business interface). So, if you want to inject the bean itself, you need to tell the container that you are using the no-interface view.

In your example, if you still want to implement your interface and inject Bean you should use the @LocalBean annotation which means that the bean exposes a no-interface view:

@Stateless
@LocalBean // <-- no-interface view
class Bean implements IBean {
...
}

interface IBean {
....
}

@SessionScoped
class Scoped {
@Inject
Bean bean; //Should be OK
}

Or, If you don't want to implement any interface, then the bean defines by default a No-Interface view:

@Stateless
class Bean {
...
}

@SessionScoped
class Scoped {
@Inject
Bean bean; //OK
}

See also:

  • What is local/remote and no-interface view in EJB?
  • Defining EJB 3.1 Views (Local, Remote, No-Interface)
  • EJB 3.1 @LocalBean vs no annotation

@EJB Injection fails in a singleton for a bean with no interface view

Be aware that your FooDAOBean is implementing a business interface via its superclass.

The Oracle Java EE tutorial states:

If the bean class implements a single interface, that interface is
assumed to the business interface. The business interface is a local
interface unless it is annotated with the javax.ejb.Remote annotation;
the javax.ejb.Local annotation is optional in this case.

Thus your FooDAOBean actually has a Local interface view instead of the no-interface view which you are expecting.

I would suggest to rename your Bean to sth like FooDAOBeanImpl. Then create a interface FooDAOBean which inherits from GenericDAOInterface. Let your Session Bean FooDAOBeanImpl now imeplent the new interface and annotate the class with @Local(FooDAOBean.class) to get a clearly defined @Local interface view. Now you able to inject FooDAOBean as expected.

can both LocalBean and Remote be annotated on one bean?

Yes, it is possible for a bean to expose multiple views (Remote business, Local business, no-interface).

The component can be the same - you just add another ways of accessing it.

Take a look at EJB 3.1 FR specification:

4.4.2.2 Session bean exposing multiple client views (p. 86).

package com.acme;

@Singleton(name="Shared")
@LocalBean
@Remote(com.acme.SharedRemote.class)
public class SharedBean { ... }

One note - I don't think the example you posted will work out-of-the-box. You're using @Remote and @Local without specifying the interface references. I don't think the container will now which interface is what. Either specify the @Remote(clazz) or annotate the interface itself as @Remote.



Related Topics



Leave a reply



Submit