EJB 3.1 @LocalBean vs no annotation
The rules are (from memory):
- Bean has a
@LocalBean
annotation -> bean has a no-interface view - Bean has a
@Local
annotation -> bean has a local view - Bean has a
@Remote
annotation -> bean has a remote view - Bean has no view annotations, but directly implements an interface which has a @Local annotation -> bean has a local view
- Bean has no view annotations, but directly implements an interface which has a @Remote annotation -> bean has a remote view
- Bean has no view annotations, but directly implements an interface which has no view annotations -> bean has a local view
- 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
Why Doesn't String's Hashcode() Cache 0
Exception in Thread 'Main' Java.Lang.Noclassdeffounderror:
How to Find Out What Keystore My Jvm Is Using
What Is the Purpose of the Java Constant Pool
What Is the Regex for "Any Positive Integer, Excluding 0"
@Transactional Method Called from Another Method Doesn't Obtain a Transaction
Differencebetween 'E', 'T', and '' for Java Generics
Java 8, Streams to Find the Duplicate Elements
How to Clear or Empty a Stringbuilder
How to Create a Modular Jsf 2.0 Application
Default Fetch Type for One-To-One, Many-To-One and One-To-Many in Hibernate
Differencebetween Iterator and Iterable and How to Use Them
How to Find Out What Type Each Object Is in a Arraylist<Object>
Jackson: How to Prevent Field Serialization
Firestore Query Documents Startswith a String
How to Prevent Java.Lang.String.Split() from Creating a Leading Empty String