I'm maintaining some older JEE code which runs fine but is using some static helper classes where an entity manager is passed in the methods from the calling EJB(s) like this:
public class StaticHelper {
public static void helpingOut(EntityManager entityManager, String value) {
// i.e. insert value
}
}
Since this doesn't seem to fit JEE very well and is not nice to unit-test, I've converted these helpers to @Stateless
EJBs like so:
@Stateless
public class StatelessHelper {
@PersistenceContext(unitName="SuperUnit")
private EntityManager entityManager;
public void helpingOut(String value) {
// i.e. insert value
}
}
Like that I can inject a mocked helper in the calling EJB with CDI-Unit.
Now, depending on the load, 1-3 instances of that stateless helper is created by the container which isn't a problem at all I would say, but anyway I thought about a @Singleton
using either @ConcurrencyManagement(ConcurrencyManagementType.BEAN)
or @Lock(LockType.READ)
to make it multithreaded - but this doesn't seem to be a good idea since EntityManager
is not thread-safe. Or does this explained here still apply?
"...The container serializes calls to each stateful and stateless session bean instance. Most containers will support many instances of a session bean executing concurrently; however, each instance sees only a serialized sequence of method calls. Therefore, a stateful or stateless session bean does not have to be coded as reentrant..."
A Singleton can implement interfaces, inherit from other classes and allow inheritance. While a static class cannot inherit their instance members. So Singleton is more flexible than static classes and can maintain state. A Singleton can be initialized lazily or asynchronously and loaded automatically by the .
Singletons may or may not have state and they refer to objects. If they are not keeping state and only used for global access, then static is better as these methods will be faster. But if you want to utilize objects and OOP concepts (Inheritance polymorphism), then singleton is better.
A Singleton Session Bean maintains the state of the bean for the complete lifecycle of the application. Singleton Session Beans are similar to Stateless Session Beans but only one instance of the Singleton Session Bean is created in the whole application and does not terminates until the application is shut down.
Business methods in Java EE (or the more recent denomination Jakarta EE) should be implemented in @Stateless
beans. That is what they are ment for. So the approach you just describe perfectly fits into the Java EE paradigm.
@Singleton
s are ment for instances containing application-wide state.
@Singleton
for beans containing business methods are models from other techologies, like Spring or Guice. In those, the business methods are not synchronized, so you have to beware that every class level attribute must be thread safe. This is not Java EE model, in which one thread is assured to access one instance of a Session Bean at any specific time (by specification), and that's what makes it safe to use with EntityManager
.
This doesn't happen with @Singletons
, and so, to use them concurrently you have to tune them with @ConcurrencyManagement
annotations.
What you just did is just right.
Clarification
It looks like I said Singleton Session Beans are not thread safe. What I ment is that concurrent access to the single instance is not allowed by default (the other way round as in Spring or Guice), and so they can be bottlenecks for business methods. To allow concurrent access you have to tune them with the aformentioned @ConcurrencyManagement
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With