The Source for Java Technology Collaboration
User: Password:



Carol McDonald's Blog

January 2008 Archives


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

Posted by caroljmcdonald on January 27, 2008 at 07:58 PM | Permalink | Comments (11)

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


I updated  this example  Sample Store Catalog app using JavaServer Faces, EJB, the Java Persistence APIs, and Seam 1.2 on Glassfish v1  to use Seam 2.0 on Glassfish V2. The Seam jar files needed to run on Glassfish have changed in Seam 2.0, (thanks to Cay Horstmann for pointing out which Seam 2.0 jars are needed)  nothing else in the example needs changing.  I also successfully tested Brian Leonard's Seam Refresh example with the Seam 2.0 jars, listed below, on Glassfish V2.

Download the Seam Sample Application Code


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  and select Open Project Folder.  This should resove 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 your web.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

Posted by caroljmcdonald on January 07, 2008 at 02:36 PM | Permalink | Comments (21)


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



I took this example  Sample Application using JSF, Spring 2.0, and Java Persistence APIs  and updated it to use the Spring 2.5 framework (which comes with Netbeans 6) on Glassfish v2.
You can dowload the  sample code   and a related presentation  JavaServer Faces, Java Persistence API, Java EE, Spring, Seam.


Explanation of the usage of JSF, Spring 2.5 , 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

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 renderer displays 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 Spring specific and Green for my code or variables)

Code Sample from:  List.jsp

<h:dataTable value='#{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 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 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 dataTableItem points to the current item in the list.

The dataTable's value is bound to the items property of the itemController ManagedBean.
This ItemController ManagedBean items property is defined as shown below:

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

  public class ItemController {

    public DataModel 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;
    }




@Controller is a Spring 2.5 "stereotype" annotation, @Repository, @Service and @Controller are role designations for a common three-tier architecture (data access objects, services, and web controllers). By clearly indicating application roles, these stereotypes facilitate the use of Spring AOP and post-processors for providing additional behavior to the annotated objects based on those roles. The @Scope("session") annotation binds a web-tier Spring-managed object to the specified scope.  The  Spring  2.5 component scanning functionality removes the need to define Web tier "controllers"  in the faces-config.xml.  The following configuration is used to trigger the auto-detection of all web controllers:

Code Sample from: applicationContext.xml

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

 

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

Code Sample from: faces-context.xml

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




The ItemController getItems() 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 DataModel instance.  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.   

The Item properties Name, Photo, and price  are displayed with the column component:

Code Sample from: List.jsp

  <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 a UIData component. 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 (item.items)  and displays the dataTableItem.price. Each time UIData iterates through the list of items, it renders one cell in each column.

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

The catalogService, and its implementation  CatalogDAO,  is defined as a Spring bean in the Spring configuration resource file /WEB-INF/applicationContext.xml :

Code Sample from: applicationContext.xml
  
    <bean id="catalogService" class="service.CatalogDAO"/>     
 
   
</beans>


  The Spring root WebApplicationContext will inject the catalogService Spring Bean into the catalogService property of the ItemController JSF ManagedBean :

Code Sample from: ItemController.java
    @Controller("itemController")
  @Scope("session")

  public class ItemController {

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



@Autowired is a Spring 2.5 annotation that makes it possible to inject dependencies that match by type. This behavior is enabled for fields, constructors, and methods. To enable this, add this to the applicationContext.xml:

Code Sample from: applicationContext.xml

<context:annotation-config/>




For more information on using JSF with Spring, see Spring - Java/J2EE Application Framework Integrating with JavaServer Faces .

Using the Java Persistence API (JPA) with Spring 2.5

The Spring bean CatalogDAO uses the Java Persistence API EntityManager Query object to return a list of items. The CatalogDAO annotates the field private EntityManager em;  with @PersistenceContext , which causes an entity manager to be injected. (note that using the @PersistenceContext annotation is the same way an Entity Manager is injected for a EJB 3.0 Session Bean.)
 

Code Sample from: CatalogDAO.java

@Repository
@Transactional
public class CatalogDAO implements CatalogService {
   
    @PersistenceContext(unitName="PetCatalogPu")
    private EntityManager em;

    @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 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: q.setMaxResults(int maxResult) sets the maximum number of results to retrieve. q.setFirstResult(int startPosition) sets the position of the first result to retrieve.

In the code below, we show the Item entity 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 @Entity annotation.
  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 Address and Product are also annotated. For more information on defining JPA entities see Pro EJB 3: Java Persistence API book.

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 Address address;
    @ManyToOne
    private Product product;

    
    public Item() { }
     
    public String getItemID() {
        return itemID;
    }

    public void setItemID(String itemID) {
        this.itemID = itemID;
    }

    public String getName() {
        return name;
    }

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

    public void setDescription(String description) {
        this.description = description;
    }

    public BigDecimal getPrice() {
       return price;
    } 

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public Product getProduct() {
        return product;
    }
    public void setProduct(Product product) {
        this.product = product;
    }

    ...
}   




The ItemController ManagedBean 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. The ItemController's <managed-bean-scope> is defined as session, a JSF Managedbean with session scope will be stored in the session meaning that the bean's properties will stay alive for the life of the Http Session.


The ItemController ItemCount  property is  used to get and display the number of Catolog items in the  data base on the List.jsp page:

Code Sample from: List.jsp

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


This ItemController ItemCount property is defined as shown below:

Code Sample from: ItemController.java

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

The ItemController getItemCount() method calls the CatalogService interface to get the count of the list of items. The CatalogDAO Spring 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 CatalogDAO implements CatalogService {
  @PersistenceContext(unitName="PetCatalogPu")
  private EntityManager em;

. . .
  @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;
  }   
    


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 action event to the application. 

Code Sample from: List.jsp

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

Continue Reading...





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds