|
Advertisement |
CRUD APPLCATION FRAMEWORK IN SEAM
Posted On February 27, 2012 by Sneha Latha filed under Enterprise
Seam is an application framework which makes development easy, by simplifying integration of existing frameworks, and making use of POJOs and annotations. It provides new stateful scopes, especially conversation, and adopts and extends the EJB3 model of extended- persistence context to provide application-scoped transaction support. This simplifies creation of applications that require multi-page user interactions.eg shopping carts. Seam does not stop with this. For basic database access in a web application, Seam provides a set of pre-built component templates, which can be re-used. The Seam documentation calls these classes as Seam Application Framework. We will call this as CRUD framework to avoid ambiguity. This “framework within a framework” reduces the amount of code you need to write when doing basic database access in a web application, using either Hibernate or JPA. In other words the inner framework is a handful of simple classes that reduce the code for performing create, read, update, and delete operations on entity instances and querying for data; if we don’t use them, the code required for performing the operations is more. For an earlier article, for creating a database-based web application, all that we did was creation of a table in a database and execution of few commands. The commands “seam setup” and “seam create-project” make use of the larger framework while the command “seam generate” the inner framework. We obtained a full-fledged running application with no code from us. The CRUD framework essentially provides prepackaged Data Access Objects (DAOs). Home is one of the DAO classes provided by Seam and is influenced by ActiveRecord of Rails -but a modification of it or even an improvement over it. We will look into the “Home” class and the crucial role played by it in the CRUD operations in the course of this article.
Example contactList application: To understand things better, at first we will have a look at contactlist application in the examples folder of in Seam distribution. We can build and deploy it, if you have Ant installed and ANT_HOME system variable set - as example applications come with build.xml files. You may have to edit the jboss.home variable in sample.build.properties file in jboss-seam\build folder. Ant will build the ear file and if there is some problem in deploying, you can manually copy the ear file and start JBoss and go to the browser and type http://locahost:8080/seam-contactlist and you will get Figure 3.If you fill Dan in First Name and click Search, You will get Figure 4.If you click Create New Contact tab you will get Figure 5.If you have a look at the source code there are only two java files Comment.java and Contact.java –both entity files. You can’t find the definitions for the methods create(),persist() or any other method required for a database operations in these classes. The controller classes supplied by the CRUD framework provide the methods necessary for database operations and they are packaged in jboss-seam.jar file. The hierarchy of controller classes in the CRUD framework is given in Figure 1:

The Controller, Persistence Controller, Home and Query classes are abstract classes and there are two implementations for Home and Query classes, to use JPA and Hibernate. We are seeing in the above figure the JPA implementations. The source code EntityHome.java is reproduced below and you can see that it contains the methods necessary for database access and understanding the code is not essential for using the class and the methods it defines.
|
EntityHome.java |
|
package org.jboss.seam.framework; import javax.persistence.EntityManager; // Referenced classes of package org.jboss.seam.framework: public class EntityHome extends Home private static final long serialVersionUID = 0xd46c243e2cb30b98L; public EntityHome() public void create() public boolean isManaged() public String update() public String persist() public String remove() public Object find() protected Object loadInstance() protected void joinTransaction() public EntityManager getEntityManager() public void setEntityManager(EntityManager entityManager) protected String getPersistenceContextName() protected String getEntityName() |
You can simply adopt the EntityHome for any entity, for example Contact, by extending the EntityHome and passing on the name of the entity as a parameter as shown below:
@Name("contactHome")
public class contactHome extends EntityHome<Contact>
{
}
The above code is sufficient and the view files can now access the create() persist() etc methods implemented in EntityHome class. You can also use xml to adopt EntityHome for an entity. The contactlist application uses xml to adopt EntityHome for the Entity Contact. Look at following extract from resources\WEB-NF\component.xml.
|
|
|
< factory name="contact" value="#{contactHome.instance}"/>//---------------2) |
1) See the use of the tag <fwk:entity-home> which takes two attributes name and entity-class. In the view files, the attributes are accessed through instances of the entity-class.ie attribute firstName in the Contact entity can be accessed from the facelets file through EL as "#{entityHome.instance.firstName}".
2)To simplify access from facelets, the factory method is used to give the instance a simple name eg contact. Now the above attribute can be accessed with the simplified name in EL "#{contact.firstName}".
But the methods create() persist() etc. cannot be accessed from the instance but from the entityHome component only as can be seen from the extract from the file editContact.xhtml from the above application.
|
<s:decorate id="firstNameDecorate"><h:inputText id="firstName" value="#{contact.firstName}" required="true"/></s:decorate>//--atrribute access
<h:commandLink id="createContact" action="#{contactHome.persist}" //…method access |
Home template What is the purpose of the Home? As mentioned earlier, Rails exerted a great influence on Seam. In the Active Record pattern followed in Rails the domain object is responsible for saving and retrieving itself from the database. Thus, in addition to encapsulating data, it encapsulates data access logic.. So Seam also did not favor anemic domain model, where-in domain objects were treated only as buckets for holding data. But the Active Record pattern bears a close resemblance to Ejb2 entity beans. Because of the tight coupling of the domain object to the framework in this model and the success of the POJO, Seam did not want to follow this pattern entirely. It designed a solution influenced by ActiveRecord pattern but based on POJOs. The Home class plays an important role in this solution.
A Home encapsulates the entity instance and the persistence manager, facilitating communication between them without making them aware of each other, as shown in the figure 2.

To the outside world, this domain object appears as a single unit, allowing the domain model to be “active” without contaminating the entity class with data access logic. The pattern followed by Seam resembles Mediator Design pattern. A Home uses the persistence manager to manipulate the persistence state of the entity instance it manages. To coordinate these state transitions, the Home performs the well-known CRUD operations by delegating the work to the persistence manager. This encapsulation and delegation is makes the Home pattern a good object-oriented design. The Mediator pattern sets the Home apart from the entity instance itself, and the Home is both transactional and stateful. ie Home works with Seam managed persistence context and provides transaction support to the entity instance. This transparent management of the entity instance is the quintessence of stateful behavior and is claimed to be more “active” than what the Active Record pattern affords.
Create a Project Create a table person with the following fields: 1) id int auto-increment 2) username varchar(20) notnull 3) name varchar(20) notnull. Create a seam project by name seamcrud by executing the command seam setup and seam create-project. Open the project with NetBeans. If you execute the command seam generate necessary files be generated by reverse engineering from the tables without any code from us. But to learn things it is better if we customize the generated code. So execute the command seam new-entity. It will ask for the entity class name. You can give the name Person. You can accept the default values suggested for the other queries. We can open the files in the IDE and customize them.
The seam-gen generated entity will have Long id Integer version and String name attributes and getters and setters for the same. We can modify the code for the following: Integer id, String name, String username. The modified code may look as under:
|
Person.java |
|
package com.mydomain.myproject.model; import java.io.Serializable; @Entity
@Id @GeneratedValue public void setId(Integer id) { @Length(max = 20) public void setUsername(String usersname) { public void setName(String name) { } |
The code generated for PersonHome.java requires only a small modification. After deletions the code may look as under:
Person.java |
|
package com.mydomain.myproject.action; import org.jboss.seam.annotations.Name; import org.jboss.seam.framework.EntityHome; import com.mydomain.myproject.model.Person; @Name("personHome") |
You can see that the class is empty.
PersonList.java You can also have a look at the code for PersonList.java.
|
PersonList.java |
|
package com.mydomain.myproject.action; import org.jboss.seam.annotations.Name; @Name("personList") |
You can also look at the following extract from personList.xhtml which accesses the resultList from the above component. The resultList is one of the objects obtained by it from EntityQuery.
|
<h:dataTable id="personList" var="person" |
personList.xhtml may be modified. The following portion may be copied
|
|
|
<h:column> |
- See how <s:link> is used.
- See how personId passed on through <f:param>
The copied portion may be pasted and modified for username as under:
|
|
|
<h:column> |
The change required in person.xhtml is as follows: The portion of the file for getting input for name is given hereunder:
|
|
|
<s:decorate id="nameField" template="layout/edit.xhtml"> //--------1) |
- See how input is obtained within <s:decorate>
- The input is set in name attribute of instance of personHome.
The same may be copied and modified for username as under:
|
|
|
<s:decorate id="usernameField" template="layout/edit.xhtml"> |
Run the Application Now you can go to the command prompt and type seam explode. You can start the server and go to the Browser and type http://localhost:8080/seamcrud and see the result as in Figure 6 and if you click Create Person button and fill up the text boxes you may get Figure 7.If You click Save button you may get “Successfully created” message.









