Skip navigation

Sample Application using JSF, Seam 2.0, and Java Persistence APIs on Glassfish V2


This Sample Store Catalog app demonstrates the usage of JavaServer Faces, a Catalog Stateful Session Bean, the Java Persistence APIs, and Seam 2. I took this example  Sample Application using JSF, Catalog Facade Stateless Session, and Java Persistence APIs  and refactored it to use Seam on Glassfish by following the steps in Brian Leonards blog Seam Refresh  and the clickable list example in the Seam Tutorial

Download the Seam Sample Application Code

Explanation of the usage of JSF, Seam, and Java Persistence APIs in a sample Store Catalog Application

The image below shows the Catalog Listing page, which allows a user to page through a list of items in a store.

listpage.jpg

DataTable  JSF component

The List.jsp page uses a JSF dataTable component to display a list of catalog items.

The dataTable component is useful when you want to show a set of results in a table. In a JavaServer Faces application, the UIData component (the superclass of dataTable)  supports binding to a collection of data objects. It does the work of iterating over each record in the data source. The HTML dataTable rendererdisplays the data as an HTML table.

In the List.jsp web page the dataTable is defined as shown below:   (Note:Redcolors are for Java EE tags, annotations code, Blue for Seamspecific and Green for my code orvariables)

        
Code Sample from:  List.jsp

<h:dataTablevalue='#{items}' var='dataTableItem' border="1"
      cellpadding="2" cellspacing="0">


The value attribute of a dataTable tag references the data to be included in the table. The var attribute specifies a name that is used by the components within the dataTable tag as an alias to the data referenced in the value attribute of dataTable.  In the dataTable tag from the List.jsp page, the valueattribute points to a list of catalog items. The var attribute points to a single item in that list. As the UIData component iterates through the list, each reference to dataTableItem points to the current item in the list.

The dataTable's value is bound to the itemsattribute of the CatalogBeanclass:


        
Code Sample from: CatalogBean.java

@Stateful

@Scope(SESSION)
@Name("catalog")
@Interceptors({org.jboss.seam.ejb.SeamInterceptor.class})

public class CatalogBeanimplements Serializable, Catalog {
   
    @DataModel
    private List<Item> items=null;

    @Factory("items")
    public void getItems() {
        if ((items==null)  || (index != firstItem) ){
           getNextItems();
        }
    }
   



The @DataModelSeam annotation exposes an attribute of type java.util.List to a JSF page as an instance of javax.faces.model.DataModel. The  <h:dataTable>  supports data binding to a collection of data objects represented by a DataModelinstance.  The data collection underlying a DataModel instance is modeled as a collection of row objects that can be accessed by a row index.  The APIs provide mechanisms to position to a specified row index, and to retrieve an object that represents the data that corresponds to the current row index.  In this case, the DataModel is made available in a session context variable nameditems.

When the List.jsp page is diplayed it will try to resolve the items context variable. Since this context variable is not initialized, Seam will call the @Factorymethod getItems(), which performs a JPA query (see getNextItems() code below) and results in a DataModel being outjected.  The @Factory annotation tells Seam to invoke the getItems()method to initialize the itemsvalue.

The @Name Seam annotation specifies catalogas the application unique component name which Seam will use to resolve references to the catalogcontext variable. Seam will instantiate the component and bind a new instance to the context variable the first time JSF encounters the variable name catalog. The instance will be bound to the context specified by the@ScopeSeam annotation. The CatalogBean is a org.jboss.seam.ScopeType.SESSIONscoped component. This means that the JSF components  can bind to the catalog  managed bean without configuring this in the faces-config.xml.

The @Stateful EJB 3.0 annotation marks this as a Stateful EJB. A Stateful EJB is used because the current chunk of items, and the user's position in the count of items in the db table, is maintained for the user's session.

The @Interceptors EJB 3.0 annotation registers the SeamInterceptor.class as an EJB interceptor for this session bean component.
The Seam framework uses  EJB interceptors to perform bijection, context demarcation, validation, etc, (the interceptor could be defined in the ejb-jar.xml instead).

 

Column JSF component

On the List.jsp page the Item Name, Photo, and Price  properties are displayed with the column component:

        
Code Sample from: List.jsp
<h:dataTablevalue='#{items}' var='dataTableItem' border="1"
      cellpadding="2" cellspacing="0">
...
  <h:column>
      <f:facet name="header">
          <h:outputText value="Price"/>
      </f:facet>
      <h:outputText value="#{dataTableItem.price}"/>
  </h:column>


The column tags represent columns of data in the dataTable component. While the dataTable component is iterating over the rows of data, it processes the column component associated with eachcolumn tag for each row in the table. As the dataTable component iterates through the list, each reference to dataTableItem points to the current item in the list.

The dataTable component  iterates through the list of items and displays the names, photos, and prices. Each time the dataTable iterates through the list of items, it renders one row in each column.

The dataTable and column tags use facets to represent rows of the table that are not repeated or updated. These include headers, footers, and captions.

Java Persistence Query API

The CatalogBeanSession EJB uses the Java Persistence API Queryobject to return a list of items. With the @PersistenceContextannotation the CatalogBean uses dependency injection to lookup and obtain a Container Managed EntityManager. Since the EntityManager can be  container managed for EJB Session Beans, the application does not have to manage its lifecycle (i.e. call the EntityManagerFactory.create() and EntityManager.close() methods).

        
Code Sample from: CatalogBean.java

  
@DataModel
   private List<Item> items=null;

   @PersistenceContext(unitName="PetCatalogPu")
   private EntityManager em;

   private int batchSize = 10;
   private int index = 0;
   private int firstItem = 0;
 
   @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
   public void getNextItems() {
        Query q = em.createQuery("select object(o) from Item as o");
        q.setMaxResults(batchSize);
        q.setFirstResult(firstItem);
        items= q.getResultList();
        index = firstItem;
   }
   

Since this query is used for Read-Only browsing, the transaction attribute in this example is specified as NOT_SUPPORTED. Queries using transaction-scoped entity managers outside of a transaction are typically more efficient than queries inside a transaction when the result type is an entity. 

The Java Persistence Query APIs are used to create and execute queries that can return a list of results.  The JPA Query interface provides support for pagination via the setFirstResult() and setMaxResults() methods: query.setMaxResults(int maxResult) sets the maximum number of results to retrieve.query.setFirstResult(int startPosition) sets the position of the first result to retrieve.

In the code below, we show the Itementity class which maps to the  ITEM table that stores the item instances. This is a typical Java Persistence entity object. There are two requirements for an entity:
  1. annotating the class with an @Entityannotation.
  2. annotating the primary key identifier with @Id
Because the fields name, description.... are basic mappings from the object fields to columns of the same name in the database table, they don't have to be annotated.  The O/R  relationships with Addressand Productare also annotated. For more information on defining JPA entities see Pro EJB 3: Java Persistence API book.

           
Code Sample from: Item.java

@Entity
@Name("item")
@Scope(ScopeType.EVENT)

public class Item implements java.io.Serializable {

   
@Id 
      private String itemID;

    private String name;   
    private String description;   
    private String imageurl;   
    private String imagethumburl; 
    private BigDecimal price;
    @OneToOne(cascade={CascadeType.PERSIST})
    private Address address;
    @ManyToOne
    private Product product;

    
    public Item() { }
    

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
   
 


    ...
}   



The @Namehttp://docs.jboss.com/seam/1.0.1.GA/reference/en/html/annotations.html#name-annotation seam annotation specifies the (application unique) component name item, which is used in the  Detail.jsp to display the selected item's attributes. The @ScopeSeam annotation binds the iteminstance to the org.jboss.seam.ScopeType.EVENTcontext.

The CatalogBeanpages through the list of items by maintaining the firstItemand batchSizeattributes and passing these as parameters to thequery.setFirstResult(int startPosition),query.setMaxResults(int maxResult) methods. The CatalogBean's scope is defined as org.jboss.seam.ScopeType.SESSION, which corresponds to the JSF managed bean session scope.


The CatalogBeanitemCountproperty is  used to get and display the number of Catologue items in the  data base:

        
Code Sample from: List.jsp

<h:outputText value="Item #{catalog.firstItem+ 1}..#{catalog.lastItem} of
     #{catalog.itemCount}"/>



The CatalogBeangetItemCount() method uses the JPA javax.persistence.Queryinterface to get the count of all items in the database item table:

        
Code Sample from: CatalogBean.java
        
   
private int itemCount= 0;

    public int getItemCount() {
        Query q = entityManager.createQuery("select count(o) from Item as o");     
       
itemCount = ((Long)q.getSingleResult()).intValue();     
        return
itemCount;
    }   
    


A JSF commandLink is  used to provide a link to click on to display the next page of items. The commandLink tag represents an HTML hyperlink and is rendered as an HTML <a> element. The commandLink tag is used to submit an actionevent to the application. 

        
Code Sample from: List.jsp

 <h:commandLinkaction="#{catalog.next}" value="Next #{catalog.batchSize}"
    rendered="#{catalog.lastItem + catalog.batchSize <= catalog.itemCount}"/>   


This commandLink actionattribute references the CatalogBean next() method that calculates the next page's first row number  and returns a logical outcome String, which causes the List page to display the next page's list . This CatalogBeannext()method is defined as shown below:

        
Code Sample from: CatalogBean.java

   public String next() {
       if (firstItem + batchSize < getItemCount()) {
           firstItem += batchSize;
           getNextItems();
       }
       return "item_list";
   }


The JavaServer Faces NavigationHandlermatches the logical outcome,  item_listagainst the navigation rules in the application configuration resource file faces-config.xmlto determine which page to access next. In this case, the JavaServer Faces implementation loads the List.jsp page after this method returns.

        
Code Sample from: faces-config.xml

  <navigation-rule>
      <navigation-case>
          <from-outcome>item_list</from-outcome>
          <to-view-id>/item/List.jsp</to-view-id>
        </navigation-case>
  </navigation-rule>


A JSF commandLinkis  used to provide a link to click on to display the previous page of items. This commandLink actionattribute  references the  CatalogBean's prev()method that calculates the previous page's first row number  and returns a logical outcome String, which causes the List page to display the previous page of items :

        
Code Sample from: List.jsp

 <h:commandLinkaction="#{catalog.prev}" value="Previous #{catalog.batchSize}"   
        rendered="#{catalog.firstItem >=catalog.batchSize}"/>


 This CatalogBeanprev()method  is defined as shown below: 
 
        
Code Sample from: CatalogBean.java

    public String prev() {
        firstItem -= batchSize;
        if (firstItem < 0) {
            firstItem = 0;
        }
        getNextItems();
        return "item_list";
    }     


A JSF commandLink is  used to provide a link to click on to display a page with the item details. This commandLink action attribute  references the CatalogBean select() method:

        
Code Sample from: List.jsp

   <h:column>
       <f:facet name="header">
          <h:outputText value="Name"/>
       </f:facet>
       <h:commandLink action="#{catalog.select}" value="#{dataTableItem.name}"/>   
   </h:column>


With Seam if you use the @DataModelSelectionwith the @DataModelannotation, when the user clicks on the link, Seam will propagate the selected row from theDataModel into the annotated attribute:

        
Code Sample from: CatalogBean.java

    @DataModelSelection
    @Out(required=false)
    private Item item;

    public String select() {
        return "item_detail";
    }



The @DataModelSelectionSeam annotation tells Seam to inject the DataModel List element corresponding to the clicked link into the itemattribute.  The @Out Seam annotation transfers the value of this attribute to the itemevent context variable, making it available to a JSP page after theactioncatalog.selectmethod execution. So when a row of the dataTable is selected, the selected row is injected to the itemattribute of the CatalogBeanStateful bean, and then outjected to the event context variable named itemwhich is used in the Detail.jsp page to display the item details.

The CatalogBean select() returns a string,  "item_detail",which causes the Detail.jsp page to display the item details. The JavaServer Faces NavigationHandlermatches the logical outcome,  item_detailagainst the navigation rules in the application configuration resource file faces-config.xml to determine which page to access next. In this case, the JavaServer Faces implementation loads theDetail.jsp page after this method returns.

        
Code Sample from: faces-config.xml

    <navigation-rule>
        <navigation-case>
            <from-outcome>item_detail</from-outcome>
            <to-view-id>/item/Detail.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>    

   

The Detail.jsp uses the outputTextcomponent to display the itemproperties:

        
Code Sample from:  Detail.jsp

    <h:outputTextvalue="#{item.name}" title="Name" />
    <h:outputText value="#{
item.description}" title="Description"/>
    <h:graphicImage url="#{item.imageurl}" title="Imageurl" />
    <h:outputText value="#{item.price}" title="Price" />
    <h:outputText value="#{item.address.city}" title="Address" />
    <h:outputText value="#{item.contactinfo.email}" title="Address"/>  




    detailpage.jpg


Conclusion
This concludes the sample application which demonstrates how to useSeam with the JSF dataTable and DataModel to page through a list of  Item Entities which are retrieved using  the CatalogBean Stateful Session EJB methods which use  the Java Persistence APIs.


Configuration of the Application for Seam 2.0, JSF, JPA, running on Glassfish V2

First I recommend reading Brian Leonard's blog Seam Refresh .  I will summarize and update those steps here:

To Open and Test Run the seampagination Project:

  • Use the Resolve Reference Problems dialog to map the ejb and web modules to their project, which are subdirectories beneath the seampagination directory.
  • After the references are resolved, right-click the seampagination project and select Open Required Projects.
  • Right-click the seampagination-EJBModule and select Resolve Reference Problems: 
    • browse to the Seam lib directory and select jboss-seam.jar and select Open. This should resove the reference to the following jars: jboss-seam.jar, hibernate.jar, hibernate-validator.jar, hibernate-annotations.jar, hibernate-commons-annotations.jar, javassist.jar, dom4j.jar, commons-logging.jar.
  • Right-click the seampagination-WebModule and select Resolve Reference Problems: 
    • Browse to the seampagination-ejb directory which is a sub-directory below the seampagination directory and select Open Project Folder.
    • Browse to the  jboss-seam-ui.jar found in Seam lib directory.  This should resolve the reference to the following jars: jboss-seam-ui.jar and jboss-el.jar.
If you want to create your own Java EE application using Seam 2.0 on Glassfish V2 with Netbeans from scratch (read the steps in Brian Leonard's blog Seam Refresh but use the SEAM 2.0 jars listed here here): 
  • Use Netbeans to create a new Enterprise Application
  • Right-click the Libraries node of the EJBModule project , choose Add Jar  and add these jars: 
    • Seam \lib\jboss-seam.jar
    • Seam \lib\hibernate.jar
    • Seam \lib\hibernate-validator.jar
    • Seam \lib\hibernate-annotations.jar
    • Seam \lib\hibernate-commons-annotations.jar
    • Seam \lib\javassist.jar
    • Seam \lib\dom4j.jar
    • Seam \lib\commons-logging.jar
  • Right-click the Libraries node of the WebModule project ,  choose Add Jar  and add these jars: 
    • your ejbModule
    • Seam \lib\jboss-seam-ui.jar
    • Seam \lib\jboss-el.jar
  • create an empty seam.properties file in the seampagination-EJBModule src\conf Folder.
  • add  the following phase listener to your faces-config.xml file under webpages web-inf:
     
    <lifecycle>
            <phase-listener>
                org.jboss.seam.jsf.SeamPhaseListener
            </phase-listener>
    </lifecycle>

  • add the following  context parameter to your web.xml file
    <context-param>
         <param-name>
              org.jboss.seam.core.init.jndiPattern
         </param-name>
         <param-value>
               java:comp/env/your ear name/#{ejbName}/local
         </param-value>  
    </context-param>
  • add the following listener class to yourweb.xml file
     
    <listener>
            <listener-class>
                org.jboss.seam.servlet.SeamListener
            </listener-class>
    </listener>
  • For any session EJB's referenced from the web, add  EJB references to your web.xml,for example:
     
    <ejb-local-ref>
         <ejb-ref-name>your ear name/CatalogBean/local</ejb-ref-name>
         <ejb-ref-type>Session</ejb-ref-type>
         <local-home/>
         <local>your package name.Catalog</local>
         <ejb-link>CatalogBean</ejb-link>
    </ejb-local-ref>
  • For any EJB's referenced from the web add  a Seam interceptor to the EJB, for example : @Interceptors({org.jboss.seam.ejb.SeamInterceptor.class})

References:





Sample Application using JSF, Spring 2.5, and Java Persistence APIs with Netbeans 6.1 and Glassfish v2


You can dowload the Sample Application using JSF, Spring 2.5, and Java Persistence APIs  on Glassfish v2 and a related presentation  JavaServer Faces, Java Persistence API, Java EE, Spring, Seam.

 

A Summary of the Technologies and Frameworks in the Sample Application

If you're not familiar with JavaServerFaces technology, the Java Persistence API, or Spring, here are brief descriptions:

  • JavaServer Faces Technology (often referred to as JSF) is a server-side user interface (UI) component framework for web applications. It simplifies the development of sophisticated interactive web UIs by providing configurable, reusable, extendable UI components, support for event handling, input converters and validators, a navigation model, a component rendering model, and a managed bean model for translating input events to server-side behavior.

  • The Java Persistence API provides a (plain old Java object) POJO-based persistence model for Java EE and Java SE applications. It handles the details of how relational data is mapped to Java objects, and it standardizes Object/Relational (O/R) mapping.

  • Spring is a lightweight, POJO-oriented, open source framework for developing Java enterprise applications. Spring does not reinvent application server functionality such as connection pooling, or provide an object-relational mapping layer. Instead it provides support for Inversion of Control (IoC), dependency injection, Aspect Oriented Programming (AOP), and an abstraction/services layer designed to make existing Java Enterprise application server technologies easier and more transparent to use.


Explanation of the usage of JSF, Spring 2.5 , and Java Persistence APIs in a sample Store Catalog Application

The sample application is an online catalog which allows a user to page through a list of items in a store.

listpage.jpg

The List.jsp page uses a JSF dataTable component to display a table of catalog items.

The dataTable component is useful when you want to show a set of results in a table. In a JavaServer Faces application, the UIData component (the superclass of dataTable)  supports binding to a collection of data objects. The UIData component does the work of iterating over each record in the collection of data objects. The HTML dataTable rendererdisplays the data as an HTML table.

In the List.jsp web page the dataTable is defined as shown below:  (Note: Red colors are for Java EE tags, annotations code, Blue for Springspecific and Green for my code orvariables)

        
Code Sample from:  List.jsp

<h:dataTablevalue='#{itemController.items}' var='dataTableItem'
 border="1"  cellpadding="2" cellspacing="0">



The value attribute of a dataTable tag references the data to be included in the table. The value attribute in the dataTable tag points to a list of catalog items identified by the expression#{itemController.items}. The value is bound to the itemsproperty of a managed bean that has the managed bean nameitemController.

The var attribute specifies a name , dataTableItem, which is used as an alias for a single item in the  dataTable.  In the dataTable tag from the List.jsppage, the value attribute points to a list of catalog items. The var attribute points to a single item in that list. As the UIData component iterates through the list, each reference to dataTableItempoints to the current item in the list.

The dataTable's value is bound to the itemsproperty of the itemControllerManagedBean.
This ItemControllerManagedBean itemsproperty is defined as shown below:

        
Code Sample from: ItemController.java
    package controller;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component; 
 
  @Component("itemController")
  @Scope("session")

  public class ItemController{

    publicDataModel getItems() {
        if (model==null  || index != firstItem){
            model=getNextItems();
        }
        return this.model;
    }
   
    public DataModel getNextItems() {      
        model = new ListDataModel(catalogService.getItems(firstItem,batchSize));
        index = firstItem;      
        return this.model;
    }




@Componentis aSpring 2.5 "stereotype" annotation. @Repository, @Service and @Controller extend @Component and are role designations for a common three-tier architecture components (data access objects, services, and web controllers).  these stereotypes facilitate the use of Spring AOP and post-processors for providing additional behavior to the annotated objects based on those roles and can also be used for auto-detection of components on the classpath.

The @Scope("session")annotation binds a web-tier Spring-managed object to the specified scope. "session"scopes a  bean definition to the lifecycle of a HTTP Session.

The  Spring  2.5 component scanning functionality removes the need to define  JSF Managed Beans or Web tier "controllers"  in the faces-config.xml, and other components in the Spring applicationContext.xml. The following configuration is used to trigger the auto-detection of all components in the controller package:

        
Code Sample from: applicationContext.xml

  <context:component-scan base-package="controller" />

 

To integrate Spring with JSF
configure the Spring  JSF 1.2ELResolver that delegates to the Spring rootWebApplicationContext, resolving name references to Spring-defined beans. Configure this resolver in yourfaces-config.xml file as follows:

        
Code Sample from: faces-context.xml

  <application>
    <el-resolver>
    org.springframework.web.jsf.el.SpringBeanFacesELResolver
    </el-resolver>
 </application>
 




The ItemControllergetItems() method wraps a List of item objects, returned from the catalogService,  in a DataModel.
UIData, the superclass of dataTable, supports data binding to a collection of data objects represented by a DataModelinstance.  The data collection underlying a DataModel instance is modeled as a collection of row objects that can be accessed by arow index.  The APIs provide mechanisms to position to a specified row index, and to retrieve an object that represents the data that corresponds to the current row index.   

The Itemproperties Name, Photo, and price  are displayed with the dataTablecolumncomponent, which displays a table column:

        
Code Sample from: List.jsp
<h:dataTablevalue='#{itemController.items}' var='dataTableItem'
 border="1"  cellpadding="2" cellspacing="0">

  <h:column>
      <f:facetname="header">
          <h:outputTextvalue="Price"/>
      </f:facet>
      <h:outputTextvalue="#{dataTableItem.price}"/>
  </h:column>


The columntags represent columns of data in a dataTable. While the UIData component is iterating over the rows of data, it processes the UIColumn component associated with each column tag for each row in the table.

The UIData component  iterates through the list of items returned by ItemControllergetItems() , ( referenced by value='#{itemController.items}') ,  and displays the dataTableItem.price. Each time UIData iterates through the list of items, it renders one row  in each column.

The dataTable and column tags use facet to represent parts of the table that are not repeated or updated in the rows. These include headers, footers, and captions.

Auto-Detection of Spring Components

The CatalogDAO,  is defined as a Spring bean by the  @Repository stereotype which extends the @Component annotation and can be  used for auto-detection of components on the classpath.

        
Code Sample from: CatalogDAO.java

package service;

@Repository
public class CatalogDAOimplements CatalogService{
   
    ...
   


The The Spring IoC container  will inject thecatalogServiceSpring Bean into the catalogServiceproperty of theItemControllerJSF ManagedBean :

        
Code Sample from: ItemController.java
   
  public class ItemController{

  private CatalogService catalogService ;

  @Autowired
  public void setCatalogService(CatalogService catalogService) {
        this.catalogService = catalogService; 
  }



@Autowired  marks a constructor, field, setter method or config method to be autowired by Spring's dependency injection facilities. @Autowired makes it possible toinject dependencies that match by type.   The setCatalogServiceis marked as @Autowired and accepts an argument of type CatalogService. This is Spring 2.5 annotation-driven dependency injection: This setter will be called passing in a Spring bean of type CatalogService, obtained by type from the Spring ApplicationContext.
To enable this, add this to the Spring applicationContext.xml:

        
Code Sample from: applicationContext.xml

<context:annotation-config/>
<context:component-scan base-package="service" />



Using the Java Persistence API (JPA) with Spring 2.5

The Spring bean CatalogDAOuses an EntityManagerQuery object in the Java Persistence API to return a list of items. If you look at the source code for CatalogDAO , you'll notice that it annotates an EntityManager field with a@PersistenceContextannotation. This injects an entity manager into the Spring Bean  the same way that an Entity Manager is injected into an Enterprise JavaBeans Technology (EJB) session bean.

        
Code Sample from: CatalogDAO.java
package service;
@Repository
@Transactional
public class CatalogDAOimplements CatalogService{
   
    @PersistenceContext(unitName="PetCatalogPu")
    private EntityManagerem;

   @Transactional(readOnly = true)
    public List<Item>  getItems(int firstItem,int batchSize) {      
       Query q = em.createQuery("select object(o) from Item as o");
       q.setMaxResults(batchSize);
       q.setFirstResult(firstItem);
       List<Item> items= q.getResultList();
       return items;      
   }
   

The createQuery method creates an instance of aQuery class for executing a Java Persistence query language statement. The setMaxResults() method inQuery sets the maximum number of results to retrieve, and the setFirstResult method sets the position of the first result to retrieve.

Item is an Entity class -- a typical Java Persistence entity object -- which maps to an ITEM table that stores the item instances. If you examine the source code forItem, you'll see that it meets the two requirements for an entity:

  • The class is annotated with an @Entityannotation.
  • The primary key identifier is annotated with an@Id annotation.


           
Code Sample from: Item.java

@Entity
public class Item implements java.io.Serializable {

   
@Id 
    private String itemID;

    private String name;   
    private String description;   
    private String imageurl;   
    private String imagethumburl; 
    private BigDecimal price;
    @OneToOne(cascade={CascadeType.PERSIST})
    private Addressaddress;
    @ManyToOne
    private Productproduct;

    
    public Item() { }
     

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
   


    ...
}   




The ItemControllerManagedBean pages through the list of Items by maintaining the firstItem and batchSize attributes and passing these as parameters to the CatalogService getItems(firstItem, batchSize) method, which gets the items for display in the table of pets.


The ItemControllerItemCount property is  used to get and display the number of Catologitems in the  data base on the List.jsp page:

        
Code Sample from: List.jsp

<h:outputTextvalue="Item #{
itemController.firstItem +1} ..#{itemController.lastItem} of #{itemController.itemCount}"/>


This ItemControllerItemCountproperty is defined as shown below:

        
Code Sample from: ItemController.java

    public int getItemCount() {      
        int count = catalogService.getItemsCount();
        return count;     
    }

The ItemControllergetItemCount() method calls the CatalogServiceinterface to get the count of the list of items. The CatalogDAOSpring bean  getItemCount() method uses the JPA Query interface to get the count of all items in the database item table:

        
Code Sample from: CatalogDAO.java
@Repository
@Transactional

  public class CatalogDAOimplements CatalogService{
  @PersistenceContext(unitName="PetCatalogPu")
  private EntityManagerem;

. . .
  @Transactional(readOnly = true)
  public int  getItemCount() {
      Query q = entityManager.createQuery(
                 "select count(o) from Item as o");     
      int count = ((Long)q.getSingleResult()).intValue();     
        return count;
  }   
    


Displaying the Next List of items

A JSF commandLinkis  used to provide a link to click on to display the next page of items. The commandLinktag represents an HTML hyperlink and is rendered as an HTML <a> element. The commandLink tag is used to submit an action event to the application. 

        
Code Sample from: List.jsp

 <h:commandLinkaction="#{
itemController.next}" value="Next #{itemController.batchSize}"
    rendered="#{itemController.lastItem + itemController.batchSize <= itemController.itemCount}"/> 


This commandLink action attribute references the ItemControllerbacking bean next() method which calculates the next page's first row number  and returns a logical outcome String, which causes the List.jsp page to display the next page's list . The ItemControllernextmethod is defined as shown below:

        
Code Sample from: ItemController.java

   public String next() {
       if (firstItem + batchSize < getItemCount()) {
           firstItem += batchSize;
       }
       return "item_list";
   }


The JavaServer Faces NavigationHandlermatches the logical outcome,  item_listagainst the navigation rules in the application configuration resource filefaces-config.xml to determine which page to access next. In this case, the JavaServer Faces implementation loads the List.jsp page after this method returns.

        
Code Sample from: faces-config.xml

  <navigation-rule>
      <navigation-case>
          <from-outcome>
item_list</from-outcome>
          <to-view-id>/item/List.jsp</to-view-id>
      </navigation-case>
  </navigation-rule>



When the List.jsp dataTable  is rendered, thevaluebinding causes the  ItemControllergetItemsmethod to be called, as discussed before, which will cause the next list of items to be displayed.             
Code Sample from: List.jsp
<h:dataTablevalue='#{itemController.items}' var='dataTableItem'
 border="1"  cellpadding="2" cellspacing="0">




Displaying an Item's Details 

A JSF commandLinkis  used to provide a link to click on to display a page with the item details. This commandLink actionattribute  references TheItemControllerdetailSetup() method:

        
Code Sample from: List.jsp

   <h:column>
       <f:facet name="header">
          <h:outputText value="Name"/>
       </f:facet>
       <h:commandLink action="#{
itemController.detailSetup}" value="#{dataTableItem.name}"/>   
   </h:column>


The ItemControllerdetailSetup() method  gets the item data from the current row of the dataModel, and returns a string which causes the Detail.jsp page to display the item details :

        
Code Sample from: ItemController.java

    public String detailSetup() {
        item = (Item) model.getRowData();
        return "item_detail";
    }


The JavaServer Faces NavigationHandlermatches the logical outcome,  item_detailagainst the navigation rules in the application configuration resource file to determine which page to access next. In this case, the JavaServer Faces implementation loads the Detail.jsp page after this method returns.

        
Code Sample from: faces-config.xml

    <navigation-rule>
        <navigation-case>
            <from-outcome>item_detail</from-outcome>
            <to-view-id>/item/Detail.jsp</to-view-id>  
        </navigation-case>
    </navigation-rule>    

   

The Detail.jsp uses the outputTextcomponent to display the ItemControllerManagedBean's itemproperties:

        
Code Sample from: detail.jsp

    <h:outputTextvalue="#{itemController.item.name}" title="Name" />
    <h:outputText value="#{itemController.item.description}" title="Description"/>
    <h:graphicImage url="#{itemController.item.imageurl}" title="Imageurl" />
    <h:outputText value="#{itemController.item.price}" title="Price" />
    <h:outputText value="#{item
Controller.item.address.city}" title="Address" />
    <h:outputText value="#{item
Controller.item.contactinfo.email}" title="Address"/>  


    detailpage.jpg



Conclusion
This concludes the sample application which demonstrates how to work with the JSF dataTableand  DataModel  to page through a list of  Item Entitieswhich are retrieved using the Catalog methods which use  the Java Persistence APIs with Spring 2.5.

Running the Sample Code

The sample code for this tip is available as a NetBeans project. You can build and run the sample code using the NetBeans IDE.


Set up the Development Environment: (these directions are also here with screenshots)

  1. Download and install NetBeans 6.1 . Get the full distribution with Java EE and Glassfish v2.
  2. Install the Spring Framework Plug-in into the NetBeans IDE: 
    • Select Tools from the NetBeans menu bar and select Plugins.
    • Select Available Plugins tab and then select Spring Framework Support and then click the Install button.
  3. Open the Admin Console of the GlassFish V2 application server in order to create the JDBC Connection pool and JDBC resource:
     
    1. Select the NetBeans Services tab window.
    2. Expand Servers.
    3. Right click GlassFish V2 and select View Admin Console.
    4. Enter values to User Name and Passwordfields - the default is admin for User Name and adminadmin for the Password
  4. Create a connection pool using the Admin Console:
     
    1. Expand Resources->JDBC.
    2. Click Connection Pools.
    3. Click New on the right of the page.
    4. For the Name field, enter PETCatalogPool.
    5. For Resource Type, select javax.sql.DataSourcefrom the drop-down menu.
    6. For Database Vendor field, select JavaDB from the drop-down menu.
    7. Click Next.
    8. Scroll down to the end of the page to see the Additional Properties section.
    9. For Connection Attributes field, enter;create=true.
    10. For DatabaseName field, enter pet-catalog.
    11. For Password field, enter app.
    12. For User field, enterapp.
    13. Click Finish.
    14. Remove the SecurityMechanism property from thePETCatalogPool:.
       
      1. Select PetCatalogPoolunder Connection Pools node on the left.
      2. Select Additional Properties tab on the right and observe that the Edit Connection Pool Propertiesare displayed.
      3. Check Security Mechanism and click Delete Properties.Click Save.
  5. Start the Java DB server using NetBeans:
     
    1. Select Tools from the NetBeans top-level menu bar and select Java DB Database->Start Server.
  6. Make sure the PetCatalogPool is operational using the Admin Console: 
    1. Start the Java DB server (if it is not started already)
    2. Select the Admin Console General tab window.
    3. Click Ping button.
    4. Make sure that the Ping Succeeded message is displayed on the top.
  7. Create a JDBC resource using the Admin Console: 
    1. Select JDBC Resourcesunder JDBC on the left of the Admin Console .
    2. Click New button on the right.
    3. For JNDI Name field, enter jdbc/PETCatalogDB.
    4. For Pool Name field, select PETCatalogPool from the drop-down menu.
    5. Click OK.
  8. Create a Database connection using NetBeans:
     
    1. Select the NetBeans Services tab window.
    2. Right click Database and select New Connection.
    3. Observe that the New Database Connection dialog box appears.
    4. For the Database URL field, enter jdbc:derby://localhost:1527/pet-catalog.
    5. For User Name field, enter app.
    6. For Password field, enter app.
    7. Click OK.
  9. Create a database using NetBeans:
    Select Tools from the NetBeans top-level menu bar and select Java DB Database->Create Database
    1. Observe that the Create Java DB Database dialog appears.
    2. For the Database Name field, enter pet-catalog.
    3. For User Name field, enter app.
    4. For Password field, enter app.
    5. Click OK.
  10. Populate the database tables  in the pet-catalog database as follows: 
    1. Under Databases, select the connection pet-catalog that you just created.
    2. Right mouse click on pet-catalog and select Excecute Command.
    3. In the SQL command window copy paste all the sql text from the file<sample_install_dir>/SpringJPA/setup/sql/javadb/catalog.sql,
    4. At the top of the window click on the icon for Run SQL. This will create all of the tables and data for the application.

Open and Run the Sample code:

  1. Download the sample code and extract its contents. You should now see the newly extracted directory as<sample_install_dir>/SpringJPA, where<sample_install_dir> is the directory where you installed the sample package. For example, if you extracted the contents to C:\ on a Windows machine, then your newly created directory should be at C:\SpringJPA.

  2. Start the NetBeans IDE. Click Open Project in the File menu and select the SpringJPA directory you just unzipped.
  3. You will see a Reference Problems dialog when you open the project. That's because you need to add the Spring Framework to the project.   click Close in the dialog.
  4. Right click the SpringJPA project libraries node and select add Library, then select Spring Framework 2.5  (the Spring Framework Plug-in which you installed earlier), then click Add Library.

  5. Build the project as follows:

     
    • Right click the SpringJPA node in the Projects window.
    • Select Clean and Build Project.

  6. Run the project as follows:

     
    • Right click the SpringJPA node in the Projects window.
    • Select Run Project.
When you run the project, your browser should display the opening page of the JSF, Java Persistence API, and Spring 2.5 Sample Application (at http://localhost:8080/SpringJPA/).

Creating your own Netbeans Project with Spring 2.5 & Glassfish  :

  1. If you want to create your own application, Create a new Netbeans Web Application:
     
    1. In Netbeans  select File New Project, then select Web ..Web Application, on the New Web Application Window, for Server select Sun Java System Applicaton server,  Java EE 5 Version,  set a project name and context path  and click Next .
    2. on the frameworks window select Spring Framework 2.5, click Finish.
  2. To Generate Entity classes from database tables: In the project window, right click on the project, select new File..Persistence Entity classes from database.  Click next, then select your datasource, tables and create your persistence unit. For more info on how to do this try out the following Hands On Lab: Java EE 5, EJB 3.0, Java Persistence API (JPA)
  3. Configuration of the XML files for Spring 2.5, JSF, and JPA, running on Glassfish. For Spring configuration modify the applicationConfiguration.xmland modify the web.xml andfaces-config.xmlas described below. 
    1.  modify the file/WEB-INF/applicationContext.xml to the war WEB-INFdirectory.  This file is where you define your Spring service beans, and resources. Below is the applicationContext.xml for the sample app.  For more information about configuring the Spring applicationContext.xml for JPA see this article: Using the Java Persistence API (JPA) with Spring 2.5           
      Code Sample from: applicationContext.xml

         
          <bean id="propertyConfigurer"
                class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
                p:location="/WEB-INF/jdbc.properties" />

             
        
          <bean id="entityManagerFactory"
                class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
                p:dataSource-ref="dataSource">
              <property name="jpaVendorAdapter">
                  <bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"
                        p:databasePlatform="${jpa.databasePlatform}"
                        p:showSql="${jpa.showSql}"/>          
                </property>
              <property name="loadTimeWeaver">
                  <bean class="org.springframework.instrument.classloading.glassfish.GlassFishLoadTimeWeaver"/>
              </property>
          </bean>    
         
          <bean id="dataSource"
                class="org.springframework.jdbc.datasource.DriverManagerDataSource"
                p:driverClassName="${jdbc.driverClassName}"
                p:url="${jdbc.url}"
                p:username="${jdbc.username}"
                p:password="${jdbc.password}" />  

       
          <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
          
          <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

        
          <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

          <tx:annotation-driven />

          <context:annotation-config/>
          <context:component-scan base-package="controller" />
          <context:component-scan base-package="service" />

          <aop:aspectj-autoproxy/>

         
      </beans>

    2. Add the spring framework ContextLoaderListener and context parameter to your application's web.xml as shown below. For more information on configuring Spring see these references: Using Spring 2 with JSF , Spring - Java/J2EE Application Framework Integrating with JavaServer FacesAdvanced Configuration of the Spring MVC Framework
                 
      Code Sample from: web.xml

          <context-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>/WEB-INF/applicationContext.xml</param-value>
          </context-param>
          <listener>
              <listener-class>
                 org.springframework.web.context.ContextLoaderListener
              </listener-class>
          </listener>
          <listener>
              <listener-class>    
                org.springframework.web.context.request.RequestContextListener     
              </listener-class>
          </listener>   

         
    3. Add the SpringBeanFacesELResolverto the faces-config.xml :            
      Code Sample from: faces-config.xml

        <application>
          <el-resolver>
         org.springframework.web.jsf.el.SpringBeanFacesELResolver
            </el-resolver>
       </application>




For additional information see:




Filter Blog

By date: