5.3. Data Access using a Session Bean
Let's go through a listing of the code for the TodoDao
class.
@Stateful @Name("todoDao") public class TodoDao implements TodoDaoInt { @In (required=false) @Out (required=false) private Todo todo; @PersistenceContext (type=EXTENDED) private EntityManager em; // Injected from pages.xml Long id; public String persist () { em.persist (todo); return "persisted"; } @DataModel private List <Todo> todos; @Factory("todos") public void findTodos () { todos = em.createQuery("select t from Todo t") .getResultList(); } public void setId (Long id) { this.id = id; if (id != null) { todo = (Todo) em.find(Todo.class, id); } else { todo = new Todo (); } } public Long getId () { return id; } public String delete () { em.remove( todo ); return "removed"; } public String update () { return "updated"; } @Remove @Destroy public void destroy() {} }
First of all notice that this is a stateful session bean. Seam can use both stateful and stateless session beans, the two most common types of EJB3 beans.
The @In
and @Out
annotations define an attribute that is injected by Seam. The attribute is injected to this object or from this object to another via a Seam context variable named todo
, a reference to the Seam registered name of our Todo
class defined in Todo.java
.
The @PersistenceContext
annotation injects the EJB3 Entity manager, allowing this object to persist objects to the database. Because this is a stateful session bean and the PersistenceContext
type is set to EXTENDED
, the same Entity Manager instance is used until the Remove method of the session bean is called. The database to be used (a persistence-unit
) is defined in the file resources/META-INF/persistence.xml
Note that this session bean has simultaneous access to context associated with web request (the form values of the todo
object), and state held in transactional resources (the EntityManager
). This is a break from traditional J2EE architectures, but Seam does not force you to work this way. You can use more traditional forms of application layering if you wish.
The @DataModel
annotation initializes the todos
property, which will be outjected or "exposed" to the view. The @Factory
annotated method performs the work of generating the todos
list, and is called by Seam if it attempts to access the exposed DataModel
property and finds it to be null. Notice the absence of property access methods for the todos
property. Seam takes care of this for you automatically.
Let's take a look at the JSF code that we use for displaying and editing the list of todos, to get an idea of how to use these interfaces in practice.