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.
Related
I am not sure whether my approach with the MVC environment in JSF is the best way to go. Since I am trying to get the most out of JSF I would like to know how my Service Layer (or Model, speaking in MVC terms) should be 'designed'.
I know the View-Controller ratio should be 1 to 1 (exceptions ruled out).
Now in what way should I design my Service Layer? Should I use one big service (don't think so)? If not, based on what should I split my services?
Note, my Service will be called from the Beans (Controllers in MVC terms) and the Service itself will call DAO's using JPA when necessary.
Thanks in advance
The service layer (the business model) should be designed around the main entity (the data model). E.g. UserService for User, ProductService for Product, OrderService for Order, etc. You should absolutely not have one huge service class or so. That's extreme tight coupling.
As to the service layer API itself, Java EE 6 offers EJB 3.1 as service layer API. In the dark J2EE ages, long time ago when EJB 2.0 was terrible to develop with, Spring was more often been used as service layer API. Some still use it nowadays, but since Java EE 6 has incorporated all the nice lessons learnt from Spring, it has become superfluous. Note that EJB (and JPA) is not available in barebones servletcontainers such as Tomcat. You'd need to install for example OpenEJB on top of it (or just upgrade to TomEE).
Regardless of the service layer API choice, best would be to keep your JSF backing bean (action)listener methods as slick as possible by performing the business job entirely in the service layer. Note that the service layer should by itself not have any JSF dependencies. So any (in)direct imports of javax.faces.* in the service layer code indicates bad design. You should keep the particular code lines in the backing bean (it's usually code which adds a faces message depending on the service call result). This way the service layer is reuseable for other front ends, such as JAX-RS or even plain servlets.
You should understand that the main advantage of the service layer in a Java EE application is the availability of container managed transactions. One service method call on a #Stateless EJB counts effectively as a single DB transaction. So if an exception occurs during one of any DAO operations using #PersistenceContext EntityManager which is invoked by the service method call, then a complete rollback will be triggered. This way you end up with a clean DB state instead of a dirty DB state because for example the first DB manipulation query succeeded, but the second not.
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
When is it necessary or convenient to use Spring or EJB3 or all of them together?
JSF Controller, Service and DAO
The 1:1 ratio between services and model entities maybe not bad if you have few entities in your app. But if it is a big app, there would be too much services.
The number of services depends upon the use cases of the app you are designing. Once you have identified them in the analysis phase, you must group them in several groups according to their functionality. Each group of use cases will be a Service, and each use case will be a method in that service. Each Service can manage several model entities (and you have to inject in it the DAOs it needs to perform its functionality). Usually the uses cases of a Service manage model entities inter-realationated in the class diagram of the model. The Services might follow the good practice of "max cohesion / min coupling".
The ratio between DAOs and model entities is 1:1. Each DAO perform CRUD operations and queries of its entity. If a method needs to query 2 relationated entities, put it in the more suitable DAO depending on the business concepts.
In the JSF presentation layer I neither have a 1:1 ratio between pages and controllers, that would be too much controllers. I group into one contrller all the pages needed to perform the use cases of each service. So the ratio 1:1 is between controllers and services, injecting each service in the controller whose pages perform its use cases.
Of course, these are general principles. You may have some particular cases in the app that broke them, but they are few.
You might not have too much services and controllers, but not too few neither because then they would have too much logic and fields. You must acchieve a compromise.
This question directly follows from another question of mine here. The last paragraph of the answer to that question mentions CDI technology.
Can you explain what is the purpose of that technology. Is there any relation of that technology with JSF and EJB? I have been through this question but I'm not clear on what is the purpose of that technology yet. I specifically want to know where it fits with other Java EE technologies like EJB and JSF.
Adding to the correct answer of Bozho:
CDI is a superset of JSF's managed beans, and JSF will eventually deprecate their own native managed bean system. In JSF 2.2 steps have already been taken for this.
CDI is not a superset of EJB beans, but they complement each other. CDI does not only provide more advanced DI to EJB beans, but is also capable of giving EJB beans a scope (mostly used for stateful beans). EJB on its turn provides transactional and security services among others , which CDI does not offer. Like JSF managed beans, EJB beans will eventually be merged into the CDI component model. Marina Vatkina (EJB spec lead) among others has strongly hinted at this.
Further reading:
How do CDI and EJB compare? interact?
CDI, when to break out the EJBs
First, CDI is a dependency-injection standard framework. It defines ways for objects to obtain their dependencies not through instantiation (private FooDao dao = new FooDao()) but via a container which creates and manages instances. You can read more about dependency injection (google/wiki).
The standard defines how that works with both JSF and EJB.
your JSF managed beans can be defined via CDI, so that you can inject services into the managed beans, and so that CDI manages the lifecycle of JSF managed beans
EJB can also benefit from the advanced dependency injection of CDI (previously they had their own, feature-poor DI).
In short, CDI binds all components in JavaEE in a way spring does with all of its components, but CDI is a standard.
Given: simple JSF webapp (no Seam), having JSF beans calling few EJB's which in turn load and persist JPA entities. What I want to is to use #Singleton annotation for ejb's and inject EntityManager instead of EntityManagerFactory:
#Singleton
public class MyEJB {
#PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
protected EntityManager em; // not EntityManagerFactory
}
Spec says that #Singleton is thread-safe, supports concurrency and transaction attributes which (from my pov) makes it safe for calling from JSF beans. I expect also performance benefits because of EntityManager not being recreated for each call and it's internal caching abilities.
My main concern here is create/update operations on JPA entities in the situation when I have several singletons and, as a result, the same count of long-living EntityManagers.
What happens if one singleton updates an JPA instance and how these
changes are populated to other singletons?
As I'm not able to close entity manager, do I need to flush it upon
each entity update?
Would it be better if these few singletons will share the same entity
manager?
I saw only few examples of such design. Why? Are there any serious
drawbacks?
Many thanks in advance!
I expect also performance benefits because of EntityManager not being recreated for each call and it's internal caching abilities.
You might save some memory using singletons, but using it everywhere in your app could make it actually slower, because as there's only one EJB to serve all the concurrent requests by various users of your app, the container locks access to the EJB and when it's busy serving a request it cannot be serving another request. However this can be alleviated to some degree using lock types (i.e. #Lock(WRITE) and #Lock(READ)).
Singletons are useful for times when you want to execute a piece of code periodically using EJB timers, or to update a cache periodically, etc.
What happens if one singleton updates an JPA instance and how these changes are populated to other singletons?
Shouldn't be any different to the way non-singleton EJBs behave.
As I'm not able to close entity manager, do I need to flush it upon each entity update?
If you use CMT, no. At the end of each transaction everything will be flushed automatically.
Would it be better if these few singletons will share the same entity manager?
Looks like premature optimization to me. Just let the container inject the EM for you.
I saw only few examples of such design. Why? Are there any serious drawbacks?
Already explained.
There is one thing I want to mention regarding changing LockType of Singleton EJBs. While in general it sounds like a good idea, you should remember that resources such as EntityManger are NOT thread-safe, so appropriate concurrent access control should be provided. You can annotate methods that access non-thread-safe resources with #Lock(WRITE), but if almost all interface methods of your Singleton EJB access such resources, you will have almost the same situation as with fully write locked one. Alternative is to use Bean Concurrency Management with manual fine-grained synchronization, but it's also questionable decision.
Because of this in general I prefer Stateless EJBs over Singleton and use latter in specific cases.
I've been developing my first Java EE app, which has a number of JPA entity classes, each of which have a corresponding EJB class for dealing with the business logic. What I've done is changed one of those beans from Stateless to SessionScoped, so I can use it to allow a user to work their way through a series of form fields, all of which are rendered on a JSF form.
However, I'm starting to think this is clearly wrong, as I'm doing things like implementing methods such as "submitStep1" and "goBackToStep2" in my EJB. These methods set indicators which are used by render elements of various tags on the JSF page, so they are clearly "presentation logic".
My question is, how should I re-structure my code? I'm thinking that I should just have one SessionScoped (or should that be stateful?) bean, which deals with the presentation logic of my JSF page, and is able to use all the other ejbs (and by extension my JPA classes). This bean would be in the presentation-tier level of my app, meaning my business logic tier wouldn't need any Session Scoped Session Beans.
Now this all makes sense to me, and is what I am probably going to do. However the reason for my question is that on my JSF xhtml pages I use JSF EL tags a lot to refer to EJB content. Are there any JPA-related pitfalls I need to watch out for when writing presentation tier classes?
I know my question is pretty vague, and not really related to a specific example. And although I've found quite a lot out about Stateful v Stateless beans on this and other sites I just want to know my intended structure is the best one.
Why don't you use backing beans for presentation purpose, as they are intended for it, and you can easyly configure its scope, and leave the EJBs to business tier?
When using entities directly on the presentation tier, you should be aware of the transaction scope, specially regarding lazy relationships. That is, normally it is used one transaction per request, what will mean that amongst different requests, the entities will become detached, so you will need to reatach them to be able to load lazy relationships. You could use a filter that does it automatically each request or handle it by hand. You could also keep the same transaction during different requests but a long transaction is normally not a good idea, specially if there are updates/creations in the DB during this transacion.
Has anyone had success building a SEAM Application without using Stateful session beans? There is some confusion on a new project in which I think several stakeholders have essentially 'banned' stateful session beans... but some development is being done in SEAM.
Most of the literature on SEAM encourages the use of Stateful Session Beans. Thoughts?
You can absolutely use Seam without stateful session beans. You don't need any type of EJB at all, if you don't want them. Seam can be deployed on a variety of app servers, including Tomcat which doesn't support the use of EJBs. Seam has the ability to mimic a lot of the functionality that EJBs provide -- session scope, transactions, etc. -- without actually using an EJB.
Using Seam with Tomcat, for example, you can have a very robust application without EJBs that is lightweight, but acts in a manner similar to an application deployed on JBoss or Websphere that does make use of EJBs.