December 20, 2014
Hot Topics:

Integrating JPA, JSF and EJB in Java EE7 Applications

  • October 10, 2013
  • By Manoj Debnath
  • Send Email »
  • More Articles »

There are several improvements in EE7; managed bean was introduced towards aligning Enterprise JavaBeans (EJBs), Java Server Faces (JSF) Managed Beans and Contexts and Dependency Injection (CDI) beans. Java EE7 continues the legacy but with some significant changes - JSF Managed Beans has begun the pruning process in favor of CDI Beans. Use of @ManagedBean from javax.faces.bean is now deprecated; instead one should use @Named from javax.inject package to signify a managed bean as a JSF controller class. Also Java EE7 brought EJB container managed transactions to the platform as a whole, using CDI interceptors, so that these can be used by CDI managed beans and other Java EE components. The improvements and its convention over configuration with annotated POJOs that use little or no XML configuration, makes JSF, EJB and JPA integration simple.

A Sample Application

The sample app is a bare minimal enterprise application that focuses on three of most commonly used components, such as JPA(Java Persistence Annotation), JSF(Java Server Faces) and EJB(Enterprise Java Beans).

Coding the Entity Beans: JPA

Entities are lightweight persistence domain objects, that typically represent a table in a relational database. A primary requirement for a POJO to become an entity bean is that the class must be annotated with javax.persistence.Entity annotation. To denote a primary key property or field, use javax.persistence.Id annotation. The following entity class, Employee, has Bean Validation constraints applied to its persistence fields. Bean validation provides a set of constraints as well as an API for defining custom constraints.

@Entity
@NamedQuery(name = "findAllEmployees", query = "SELECT e FROM Employee e")
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;    
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       private Long id;
       @NotNull
       private String firstName;
       private String middleName;
       @NotNull
       private String lastName;
       @Temporal(TemporalType.DATE)      //signifies a date attribute
       @Past         //value should precede the current date, succeed is @Future
       private Date dob;
       @NotNull
       @Pattern(regexp = "^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?"
            + "(\\d{4})$", message = "{invalid.phonenumber}")
       private String phone;
       @NotNull
       @Pattern(regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\."
                     + "[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9]"
              + "(?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9]"
              + "(?:[a-z0-9-]*[a-z0-9])?", 
              message = "{invalid.email}")
       private String email;
…
//getters and setters omitted for brevity.

The @NotNull annotation specifies that those fields are required. If a new Employee is created where the fields with annotation are @NotNull, Bean Validation will throw a validation error. Similarly, if a previously created instance of Employee has been modified so that the fields actually have null values, a validation error will be thrown. The email field has an @Pattern constraint applied to it, with a complicated regular expression that matches most valid email addresses. If the value of email doesn't match this regular expression, a validation error will be thrown. The phone field has the same @Pattern constraint. The regular expression matches ten digit telephone numbers of the form (xxx) xxx-xxxx. The birthday field is annotated with the @Past constraint, which ensures that the value of birthday must be in the past.

Coding the Business Logic: EJB

The enterprise class for our example is called EmployeeEJB. This class implements two business methods: findEmployees() and addNew(). Because the enterprise bean class doesn't implement a business interface, the enterprise bean exposes a local, no-interface view. The public method in enterprise bean classes are available to clients that obtain a reference to EmployeeEJB. The source code for Employee EJB is as follows:

@Stateless
public class EmployeeEJB {
    @PersistenceContext(unitName = "Simple_JPA_EJB_JSF_ProjectPU")
    private EntityManager entityManager;
       
       public List<Employee> findEmployees(){
              TypedQuery<Employee> query = entityManager.createNamedQuery("findAllEmployees", Employee.class);        
              return query.getResultList();
       }
       
       public Employee addNew(Employee employee) {
              entityManager.persist(employee);
              return employee;
       }
}

Coding the Controller: Managed Bean

Managed bean is used to interact with other layers of the enterprise application, in our case EJB layer or perform validation. Managed bean is closely associated with JSF (Java Server Faces) serving as backing beans, which define properties and functions for UI components on a page.

@Named(value = "employeeController")
@RequestScoped
public class EmployeeController {
 
    @EJB
    private EmployeeEJB employeeEJB;
    private Employee employee = new Employee();
    private List<Employee> employeeList = new ArrayList<>();
 
   public List<Employee> getEmployeeList() {
        employeeList = employeeEJB.findEmployees();
        return employeeList;
    }
 
   public String viewEmployee(){
        return "employeeList.xhtml";
    }
   
    public String addNewEmployee() {
        employee = employeeEJB.addNew(employee);
        employeeList = employeeEJB.findEmployees();
        return "employeeList.xhtml";
    }
…
//getters and setters omitted for brevity.
}

Coding Web Pages: JSF

JSF provides the graphical components to the web and our example has two JSF pages: newEmployee.xhtml and listEmployee.xhtml.

Writing newEmployee.xhtml

The newEmployee.xhtml page is a form that allows the user to enter the data needed to create an Employee POJO (first name, middle name, last name, date of birth, phone, email).

Note: <xml...><!DOCTYPE...><html xmlns=...> declarations are omitted for brevity.
 
    <h:head> <title>Creates a new Employee</title></h:head>
    <h:body>
       <h:form>
         <h:panelGrid columns="2" >
         <h:outputLabel value="First Name : "/>
         <h:inputText value="#{employeeController.employee.firstName}"/>
         <h:outputLabel value="Middle Name :"/>
         <h:inputText value="#{employeeController.employee.middleName}"/>
         <h:outputLabel value="Last Name : "/>
         <h:inputText value="#{employeeController.employee.lastName}"/>
         <h:outputLabel value="Date of Birth : "/>
         <h:inputText value="#{employeeController.employee.dob}">
              <f:convertDateTime pattern="dd/mm/yyyy"/>
         </h:inputText>
         <h:outputLabel value="Phone : "/>
         <h:inputText value="#{employeeController.employee.phone}"/>
         <h:outputLabel value="Email : "/>
         <h:inputText value="#{employeeController.employee.email}"/>
         </h:panelGrid>
       <h:commandButton value="Add New Employee"                                  
                     action="#{employeeController.addNewEmployee}"/>            
         </h:form>
        </ui:define>
    </h:body>

As shown in the figure below, all the data is entered in text fields.

Text Fields
Text Fields

When the Add New Employee button is pressed, the addNewEmployee() method of the managed bean is invoked, and the EJB persists the Employee object to the database. The Expression Language dynamically binds the value of a component to the corresponding property in the managed bean. So the following code:

<h:inputText value="#{employeeController.book.firstName}"/>

…will set the value of the firstName attribute of the Employee with the content of the input text component. EmployeeController is the default name for our managed bean [@Named("employeeController")], so the code above is identical to:

employeeController.getEmployee().setFirstName("the value of the input text component")

Writing listEmployee.xhtml

When the submit button is clicked in the newEmployee.xhtml page, the addNewEmployee() method of the managed bean is invoked, an employee is persisted, the list of all employees is retrieved into employeelist, and, if no exception is thrown, the name of the page to navigate to is returned: listEmployee.xhtml. The listEmployee.xhtml page displays all the employees from the employeelist property of the managed bean. A link allows you to go back to the newEmployee.xhtml page to create another employee. The code of the listEmployee.xhtml page uses different components but has the same underlying ideas as the previous page. The most important component is the one that displays the data in a table:

<h:dataTable value="#{employeeController.employeeList}" var="emp">

The <h:dataTable> tag binds to the employeeList attribute of the managed bean (an ArrayList of employees) and declares the variable emp to iterate through the list. Then, inside the <h:dataTable> tag, you can use expressions such as #{emp.firstName} to get the firstName attribute of an employee. Each column of the table is defined with an <h:column> tag. At the bottom of the page, the <h:link> tag creates an HTML link that, when clicked, navigates back to the newEmployee.xhtml page).

Note: <xml...><!DOCTYPE...><html xmlns=...> declarations are omitted for brevity.
 
    <h:head> <title>Employee List</title> </h:head>
    <h:body>
    <h:dataTable value="#{employeeController.employeeList}" var="emp"  border="1">
         <h:column>
              <f:facet name="header">
                  <h:outputText value="First Name"/>
              </f:facet>
                  <h:outputText value="#{emp.firstName}"/>
               </h:column>
               <h:column>
                    <f:facet name="header">
                        <h:outputText value="Middle Name"/>
                    </f:facet>
                    <h:outputText value="#{emp.middleName}"/>
                </h:column>
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="Last Name"/>
                    </f:facet>
                    <h:outputText value="#{emp.lastName}"/>
                </h:column>
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="Date of Birth"/>
                    </f:facet>
                    <h:outputText value="#{emp.dob}"/>
                </h:column>
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="Phone"/>
                    </f:facet>
                    <h:outputText value="#{emp.phone}"/>
                </h:column>
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="Email"/>
                    </f:facet>
                    <h:outputText value="#{emp.email}"/>
                </h:column>
            </h:dataTable>
            <h:form>
            <h:link outcome="index.xhtml" value="Add new Employee"/>
            </h:form>
    </h:body>

Add New Employee

Conclusion

XML configuration requirement for the above example is almost none except a little for the database connection in persistence.xml. The intention was to write a small if not the smallest enterprise application. Library and configuration requirements are kept to a bare minimum.


Tags: Java, JSF, EJB, JPA, Java EE 7




Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel