Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF Controller, Service and DAO

I'm trying to get used to how JSF works with regards to accessing data (coming from a spring background)

I'm creating a simple example that maintains a list of users, I have something like

<h:dataTable value="#{userListController.userList}" var="u">     <h:column>#{u.userId}</h:column>     <h:column>#{u.userName}</h:column> </h:dataTable> 

Then the "controller" has something like

@Named(value = "userListController") @SessionScoped public class UserListController {     @EJB     private UserListService userListService;      private List<User> userList;      public List<User> getUserList() {         userList = userListService.getUsers();         return userList;     } } 

And the "service" (although it seems more like a DAO) has

public class UserListService {      @PersistenceContext     private EntityManager em;      public List<User> getUsers() {         Query query = em.createQuery("SELECT u from User as u");         return query.getResultList();     } } 

Is this the correct way of doing things? Is my terminology right? The "service" feels more like a DAO? And the controller feels like it's doing some of the job of the service.

like image 344
PDStat Avatar asked Jun 04 '15 09:06

PDStat


People also ask

Is DAO same as controller?

The Controller is a server side component (for web apps) that accepts requests from View clients, updates the Model appropriately, and sends results back to any and all View clients that need it. Service/DAO extends those layers to the server side.

Can you use @service over a DAO?

In your scenario, it has no impact on application flow whether you use @Service or @Repository, application will work as they are elligible for autowiring. But standard practice is to use @Repository for dao classes.

Is a DAO part of service layer?

5. The Service Layer. The DAO layer's main goal is to handle the details of the persistence mechanism, while the service layer stands on top of it to handle business requirements. Here, the service is a named component.


1 Answers

Is this the correct way of doing things?

Apart from performing business logic the inefficient way in a managed bean getter method, and using a too broad managed bean scope, it looks okay. If you move the service call from the getter method to a @PostConstruct method and use either @RequestScoped or @ViewScoped instead of @SessionScoped, it will look better.

See also:

  • Why JSF calls getters multiple times
  • How to choose the right bean scope?

Is my terminology right?

It's okay. As long as you're consistent with it and the code is readable in a sensible way. Only your way of naming classes and variables is somewhat awkward (illogical and/or duplication). For instance, I personally would use users instead of userList, and use var="user" instead of var="u", and use id and name instead of userId and userName. Also, a "UserListService" sounds like it can only deal with lists of users instead of users in general. I'd rather use "UserService" so you can also use it for creating, updating and deleting users.

See also:

  • JSF managed bean naming conventions

The "service" feels more like a DAO?

It isn't exactly a DAO. Basically, JPA is the real DAO here. Previously, when JPA didn't exist, everyone homegrew DAO interfaces so that the service methods can keep using them even when the underlying implementation ("plain old" JDBC, or "good old" Hibernate, etc) changes. The real task of a service method is transparently managing transactions. This isn't the responsibility of the DAO.

See also:

  • I found JPA, or alike, don't encourage DAO pattern
  • DAO and JDBC relation?
  • When is it necessary or convenient to use Spring or EJB3 or all of them together?

And the controller feels like it's doing some of the job of the service.

I can imagine that it does that in this relatively simple setup. However, the controller is in fact part of the frontend not the backend. The service is part of the backend which should be designed in such way that it's reusable across all different frontends, such as JSF, JAX-RS, "plain" JSP+Servlet, even Swing, etc. Moreover, the frontend-specific controller (also called "backing bean" or "presenter") allows you to deal in a frontend-specific way with success and/or exceptional outcomes, such as in JSF's case displaying a faces message in case of an exception thrown from a service.

See also:

  • JSF Service Layer
  • What components are MVC in JSF MVC framework?

All in all, the correct approach would be like below:

<h:dataTable value="#{userBacking.users}" var="user">     <h:column>#{user.id}</h:column>     <h:column>#{user.name}</h:column> </h:dataTable> 
@Named @RequestScoped // Use @ViewScoped once you bring in ajax (e.g. CRUD) public class UserBacking {      private List<User> users;      @EJB     private UserService userService;      @PostConstruct     public void init() {         users = userService.listAll();     }      public List<User> getUsers() {         return users;     }  } 
@Stateless public class UserService {      @PersistenceContext     private EntityManager em;      public List<User> listAll() {         return em.createQuery("SELECT u FROM User u", User.class).getResultList();     }  } 

You can find here a real world kickoff project here utilizing the canonical Java EE / JSF / CDI / EJB / JPA practices: Java EE kickoff app.

See also:

  • Creating master-detail pages for entities, how to link them and which bean scope to choose
  • Passing a JSF2 managed pojo bean into EJB or putting what is required into a transfer object
  • Filter do not initialize EntityManager
  • javax.persistence.TransactionRequiredException in small facelet application
like image 163
BalusC Avatar answered Sep 24 '22 17:09

BalusC