1.2.1.2. The stateless session bean class: RegisterAction.java
Most Seam application use session beans as JSF action listeners (you can use JavaBeans instead if you like).
We have exactly one JSF action in our application, and one session bean method attached to it. In this case, we'll use a stateless session bean, since all the state associated with our action is held by the User bean.
This is the only really interesting code in the example!
@Stateless
@Name("register")
public class RegisterAction implements Register
{
@In
private User user;
@PersistenceContext
private EntityManager em;
@Logger
private Log log;
public String register()
{
List existing = em.createQuery(
"select username from User where username=#{user.username}")
.getResultList();
if (existing.size()==0)
{
em.persist(user);
log.info("Registered new user #{user.username}");
return "/registered.jsp";
}
else
{
FacesMessages.instance().add("User #{user.username} already exists");
return null;
}
}
}
|
The EJB standard |
|
The |
|
The EJB standard |
|
The Seam |
|
The action listener method uses the standard EJB3 |
|
Notice that Seam lets you use a JSF EL expression inside EJB-QL. Under the covers, this results in an ordinary JPA |
|
The |
|
JSF action listener methods return a string-valued outcome that determines what page will be displayed next. A null outcome (or a void action listener method) redisplays the previous page. In plain JSF, it is normal to always use a JSF navigation rule to determine the JSF view id from the outcome. For complex application this indirection is useful and a good practice. However, for very simple examples like this one, Seam lets you use the JSF view id as the outcome, eliminating the requirement for a navigation rule. Note that when you use a view id as an outcome, Seam always performs a browser redirect. |
|
Seam provides a number of built-in components to help solve common problems. The |
Note that we did not explicitly specify a @Scope this time. Each Seam component type has a default scope if not explicitly specified. For stateless session beans, the default scope is the stateless context. Actually, all stateless session beans belong in the stateless context.
Our session bean action listener performs the business and persistence logic for our mini-application. In more complex applications, we might need to layer the code and refactor persistence logic into a dedicated data access component. That's perfectly trivial to do. But notice that Seam does not force you into any particular strategy for application layering.
Furthermore, notice that our session bean has simultaneous access to context associated with the web request (the form values in the User object, for example), and state held in transactional resources (the EntityManager object). This is a break from traditional J2EE architectures. Again, if you are more comfortable with the traditional J2EE layering, you can certainly implement that in a Seam application. But for many applications, it's simply not very useful.
Example 1.2.