JSF Service Layer
Asked Answered
A

2

21

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

Airflow answered 22/10, 2012 at 12:22 Comment(0)
B
41

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:

Bailar answered 22/10, 2012 at 13:55 Comment(6)
So.. The Service would have a Ratio of 1 to 1 if you compare it to the DAO's (and for that, Entities)? The rest of your explanation is 100% clear, the purpose of my service is already ok (so business logic, no JPA logic, no JSF logic). I will need to look into the right scopes et cetera some more. Thank you once again :)Airflow
Not exactly 1:1. You can have multiple DAOs injected in a single service class. Depends on whether the entity itself has any child entities.Bailar
@Bailar is it common to have one hibernate class declared as a JSF bean? For example, I have a Company view (it has the properties name, address, contact, etc). I am having a problem because besides all of the Company properties, I have a List<Company>. It is giving me an error because since it is a hibernate class, it is trying to find a column of type List<Company>, which doesn't exist. I am able to solve the problem by making it transient. But is this a good practice?Excellence
@Erick: Check the "See also" links for concrete examples of proper usage of entity classes and service classes in backing bean classes.Bailar
You should understand that the main advantage of the service layer in a Java EE application is the availability of container managed transactions. i like thisMargaretmargareta
@Bailar And what about this solution : EJBs for some abstract facades (Services Layer) and CDI beans for controllers behind the facade (business Layer) Entities for model (Data Access Layer)?Lupe
B
3

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.

Bisayas answered 29/10, 2014 at 17:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.