I have a stateless EJB that using container managed transactions. Can I have a method in that EJB that can use bean managed transaction. I know I can make the whole EJB to use the bean managed transactions by using the attribute #TransactionManagement(TransactionManagementType.BEAN)
No, you cannot switch between container-managed and bean-managed transactions on a per-method basis. You either need to use entirely bean-managed transactions, or you would need to split your logic into two separate EJBs.
(I cannot think of a reason why this must be the case. I think the EJB spec could have made BEAN be just another transaction attribute type rather than having a BMT/CMT distinction. Perhaps it was felt that would make the transaction model too complicated, or there weren't sufficient use-cases to try that approach.)
Related
In ASP.NET the default lifecycle of objects created in IoC container is per web request. While learning SpringBoot + Webflux, I found that the default lifecycle (Bean, Repository, Service, etc) created by the IoC container is singleton. I know I can change the default scope like this:
#Scope("prototype")
but I have not yet found an example where it would be used. So if IoC creates all object as singletons, how come there are no problems with concurrency. Can someone please explain this to me.
It's a good question. Generally speaking where concurrency is an issue, for example a transaction context in the database layer, springbook uses a thread based locking mechanism. See for example 1.2. Understanding the Spring Framework Transaction Abstraction. Otherwise, yes, anything injected with CDI is a singleton unless specifically annotated otherwise. That means that you should not keep state variables in your #Component or #Service classes. As long as the methods use only parameters passed in or variable local to the method concurrency isn't an issue because ever variable is created on the stack which is unique for each call. I have seen an application work great up until the day two people log in at once.
If you have to have a class with state variables you need to do a new of that class.
Each spring-context is created with a unique thread, so where objects are created or injected that are not stateless then state information is attached to the spring-context which runs in its own thread.
See also How does Spring bean Handle concurrency
I'm a little confused by the mixed use of JSF2+Spring+EJB3 or any combination of those. I know one of the Spring principal characteristics is dependency injection, but with JSF managed beans I can use #ManagedBean and #ManagedProperty anotations and I get dependency injection functionality. With EJB3 I'm even more confused about when to use it along with JSF or if there is even a reason to use it.
So, in what kind of situation would it be a good idea to use Spring+JSF2 or EJB3+JSF2?
Until now I have created just some small web applications using only JSF2 and never needed to use Spring or EJB3. However, I'm seeing in a lot of places that people are working with all this stuff together.
First of all, Spring and EJB(+JTA) are competing technologies and usually not to be used together in the same application. Choose the one or the other. Spring or EJB(+JTA). I won't tell you which to choose, I will only tell you a bit of history and the facts so that you can easier make the decision.
Main problem they're trying to solve is providing a business service layer API with automatic transaction management. Imagine that you need to fire multiple SQL queries to perform a single business task (e.g. placing an order), and one of them failed, then you would of course like that everything is rolled back, so that the DB is kept in the same state as it was before, as if completely nothing happened. If you didn't make use of transactions, then the DB would be left in an invalid state because the first bunch of the queries actually succeeded.
If you're familiar with basic JDBC, then you should know that this can be achieved by turning off autocommit on the connection, then firing those queries in sequence, then performing commit() in the very same try in whose catch (SQLException) a rollback() is performed. This is however quite tedious to implement everytime.
With Spring and EJB(+JTA), a single (stateless) business service method call counts by default transparently as a single full transaction. This way you don't need to worry about transaction management at all. You do not need to manually create EntityManagerFactory, nor explicitly call em.getTransaction().begin() and such as you would do when you're tight-coupling business service logic into a JSF backing bean class and/or are using RESOURCE_LOCAL instead of JTA in JPA. You could for example have just the following EJB class utilizing JPA:
#Stateless
public class OrderService {
#PersistenceContext
private EntityManager em;
#EJB
private ProductService productService;
public void placeOrder(Order newOrder) {
for (Product orderedproduct : newOrder.getProducts()) {
productService.updateQuantity(orderedproduct);
}
em.persist(newOrder);
}
}
If you have a #EJB private OrderService orderService; in your JSF backing bean and invoke the orderService.placeOrder(newOrder); in the action method, then a single full transaction will be performed. If for example one of the updateQuantity() calls or the persist() call failed with an exception, then it will rollback any so far executed updateQuantity() calls, and leave the DB in a clean and crisp state. Of course, you could catch that exception in your JSF backing bean and display a faces message or so.
Noted should be that "Spring" is a quite large framework which not only competes EJB, but also CDI and JPA. Previously, during the dark J2EE ages, when EJB 2.x was extremely terrible to implement (the above EJB 3.x OrderService example would in EJB 2.x require at least 5 times more code and some XML code). Spring offered a much better alternative which required less Java code (but still many XML code). J2EE/EJB2 learned the lessons from Spring and came with Java EE 5 which offers new EJB3 API which is even more slick than Spring and required no XML at all.
Spring also offers IoC/DI (inversion of control; dependency injection) out the box. This was during the J2EE era configured by XML which can go quite overboard. Nowadays Spring also uses annotations, but still some XML is required. Since Java EE 6, after having learned the lessons from Spring, CDI is offered out the box to provide the same DI functionality, but then without any need for XML. With Spring DI #Component/#Autowired and CDI #Named/#Inject you can achieve the same as JSF does with #ManagedBean/#ManagedProperty, but Spring DI and CDI offers many more advantages around it: you can for example write interceptors to pre-process or post-process managed bean creation/destroy or a managed bean method call, you can create custom scopes, producers and consumers, you can inject an instance of narrower scope in an instance of broader scope, etc.
Spring also offers MVC which essentially competes JSF. It makes no sense to mix JSF with Spring MVC. Further Spring also offers Data which is essentially an extra abstraction layer over JPA, further minimizing DAO boilerplate (but which essentially doesn't represent the business service layer as whole).
See also:
What exactly is Java EE?
JSF Controller, Service and DAO
#Stateless beans versus #Stateful beans
There's no real easy answer here as Spring is many things.
On a really high level, Spring competes with Java EE, meaning you would use either one of them as a full stack framework.
On a finer grained level, the Spring IoC container and Spring Beans compete with the combination of CDI & EJB in Java EE.
As for the web layer, Spring MVC competes with JSF. Some Spring xyzTemplate competes with the JPA interfaces (both can use eg Hibernate as the implementation of those).
It's possible to mix and match; eg use CDI & EJB beans with Spring MVC, OR use Spring Beans with JSF.
You will normally not use 2 directly competing techs together. Spring beans + CDI + EJB in the same app, or Spring MVC + JSF is silly.
Hy,
I have read that EJBs always have to run inside a transaction, is this true? I mean,why cant I use the ejb container to inject a dependency in some bean like spring but without transtional environment?
Thanks
By default EJB's always use transactions but you can mark the bean or more the specific each method not to use transactions using annotation #TransactionAttribute(TransactionAttributeType.NEVER).
Reading these notes. On the EBean site page. There is a paragraph that contains:
"The natural way to manage the EntityManager with a EJB3 container is
to use a Stateful Session Bean."
Also there was an exposed problem like
"How to manage EntityManager during "User Think time"?
Thus, the question: What does the EJB stateless bean do/provide that could resolve the mentioned issue with "user-think-time" ?
I guess ejb provides: "Session Management", but what is the problem to store the session on ThredLocal variable and provide it to the user on demand? And not to use EJB. Does ejb have some one-stop solution for this?
I mean, the article says that: it is bad to use the concept of Session (in hibernate) or EntityManager - because of this issue. So, it says: not need to use this at all except if you use EJB stateless bean or if you are able to provide the session management mechanism by yourself (which supposed to be hard to implement?)
First, keep in mind that the entire article is focused on the problem of managing an EntityManager when running outside of a container. The reason is that container-managed JPA injects transaction-aware EntityManager proxies when you use #PersistenceContext.
I don't know what "user think time" is, so I don't know what problem needs to be solved. As you note, you could use a ThreadLocal to manage your EntityManager if you cannot use container-managed JPA for some reason. Of course, you must be careful to properly clear and scope the contents of the ThreadLocal.
Ultimately, there is very little that EJB provides that you couldn't do yourself if you invested enough effort. Choosing to use EJB is the same as choosing to use any other library/architecture: someone else maintains it, improves it, etc., but you have to adapt to the infrastructure. EJB perhaps has a slight advantage because it's backed by a standard that many companies implement.
I am using Spring framework. Should my service classes be created as singletons? Can someone please explain why or why not? Thanks!
Yes, they should be of scope singleton.
Services should be stateless, and hence they don't need more than one instance.
Thus defining them in scope singleton would save the time to instantiate and wire them.
singleton is the default scope in spring, so just leave your bean definitions as they are, without explicitly specifying the scope attribute.
You can read more about scopes in the spring docs.
Spring is easier to use if you stick with singleton-scoped beans. Singletons are its "default position", if you like. Yes, it supports other scopes (using scope="xyz" in the XML file), but it makes things harder to use and hurts performance.
Essentially, unless you have a good reason to do otherwise, stick with singletons.
You need mostly singletons. (Spring default.) Singletons must be thread-safe, because parallel requests will use the same single instance. In fact, they must be completely stateless, because it can be destroyed and recreated at any time.
If you need to keep track of state inside of your bean (you should not, this should be in the database or stored in the request), you will get many instances of the same type of bean, memory usage goes up with the number of requests, whereby with singletons you will still have just one instance.
Even if you scope you beans to a request, they must still need be at least thread-safe (requests coming from the same browser at the same time).
Service layer should be Singleton, otherwise for every incoming request a new object will be created and these objects are heavy contains business logic and lots of line of code. They must be Singleton.