Tuesday Aug 11, 2009

Java EE 6 Pet Catalog with GlassFish v3 preview and MySQL


Java EE 6 Pet Catalog with GlassFish v3 preview and MySQL


This Pet Catalog app explains a web application that uses JSF 2.0, Java EE 6, GlassFish and MySQL. I took this example  GlassFish and MySQL, Part 2: Building a CRUD Web Application With Data Persistence and modified it to use some of the new features of JSF 2.0 and Java EE 6.
http://www.netbeans.org/kb/samples/index.html 

Explanation of the usage of JSF 2.0 and Java EE 6 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.



JSF 2.0 Facelets XHTML instead of JSP

For JSF 2.0, Facelets XHTML is the preferred way to declare JSF Web Pages. JSP is supported for backwards compatibility, but not all JSF 2.0 features will be available for views using JSP as their page declaration language.  JSF 2.0 Facelets has some nice features like templating (similar in functionality to Tiles) and composite components, which I'm not going to discuss here but you can read about that in this article: http://www.ibm.com/developerworks/java/library/j-jsf2fu2/index.html and in this Tech Tip Composite UI Components in JSF 2.0.


The Catalog application's resources


JSF 2.0 standardizes how to define web resources. Resources are any artifacts that a component may need in order to be rendered properly -- images, CSS, or JavaScript files.  With JSF 2.0 you put resources in a resources directory or a subdirectory.


In your Facelets pages, you can access css files with the  <h:outputStylesheet>,  javascript files with the <h:outputScript> , and images with the <h:graphicImage> JSF tags. The list.xhtml uses the  <h:outputStylesheet tag to load the styles.css stylesheet , and the <h:graphicImage tag to display images from the resources as shown below:

Code Sample from:  list.xhtml

<h:outputStylesheet name="css/styles.css" target="body"/>

<h:graphicImage library="images" name="banner_logo.gif"  />   




The Catalog application uses a resource bundle to contain the static text and error messages used by the Facelets pages. Putting messages in a resource bundle makes it easier to modify and internationalize your Application text.  The messages are in a properties file in a java package directory.

Code Sample from:  messages.properties 

Title=Pet Catalog
Next=Next
Previous=Prev
Name=Name



The resource bundle is configured in the faces-config.xml File (you don't need any other configuration in the faces-config.xml for JSF 2.0, as explained later you no longer have to configure managed beans and navigation with XML).


Code Sample from:  faces-config.xml

<application>
    <resource-bundle>
        <base-name>web.WebMessages</base-name>
        <var>msgs</var>
    </resource-bundle>
</application>




The List.xhtml facelets page uses a JSF dataTable component to display a list of catalog items in an html table.  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.xhtml web page the dataTable is defined as shown below:  (Note: Red colors are for Java EE tags, annotations code,  and Green is for my code or variables)

Code Sample from:  list.xhtml

<h:dataTable value='#{catalog.items}' var='row' 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 dataTable component iterates through the list, each reference to dataTableItem points to the current item in the list.

JSF 2.0 Annotations instead of XML configuration

The dataTable's value is bound to the items property of the catalog managed bean. With JSF 2.0 managed beans do not have to be configured in the faces-config.xml file, you annotate the managed beans instead as shown below:

Code Sample from: Catalog.java


@ManagedBean
@SessionScoped
public class Catalog implements Serializable {




By convention, the name of a managed bean is the same as the class name, with the first letter of the class name in lowercase. To specify a managed bean name you can use the name attribute of the ManagedBean annotation, like this: @ManagedBean(name = "Catalog").


This Catalog ManagedBean items property is defined as shown below:

Code Sample from: Catalog.java

    private List<Item> items = null;

    public List<Item> getItems() {
        if (items == null) {
            getPagingInfo();
            items = getNextItems(pagingInfo.getBatchSize(), pagingInfo.getFirstItem());
        }
        return items;
    }





The getItems() method returns a List of item objects. The JSF dataTable, supports data binding to a collection of data objects.  The dataTable object 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, imagethumburl, and price are displayed with the column component:

Code Sample from: list.xhtml

<h:dataTable var="row" value="#{catalog.items}">
  <h:column>
      <f:facet name="header">
          <h:outputText value="#{msgs.Name}"/>
      </f:facet>
      <h:commandLink action="#{catalog.showDetail(row)}" value="#{row.name}" />
  </h:column>

  <h:column>
      <f:facet name="header">
          <h:outputText value="#{msgs.Photo}"/>
      </f:facet>
<h:graphicImage library="images" name="#{row.imagethumburl}"/>
  </h:column>

  <h:column>
      <f:facet name="header">
          <h:outputText value="#{msgs.Price}"/>
      </f:facet>
      <h:outputText value="#{row.price}"/>
  </h:column>
</h:dataTable>


The column tags represent columns of data in a dataTable component. While the dataTable 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 dataTable component  iterates through the list of items (catalog.items)  and displays the item (var="row") attribute value. 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.

Java EE 6: JSF 2.0,  EJB 3.1, and Java Persistence API (JPA)  2.0

The Catalog ManagedBean annotates the field private ItemFacade itemFacade;  with @EJB , which causes an itemFacade EJB to be injected when the managed bean is instatiated. The Catalog getNextItems method calls the ItemFacade Stateless EJB which uses the Java Persistence API EntityManager Query object to return a list of items.


Code Sample from: Catalog.java

@ManagedBean
@SessionScoped
public class Catalog implements Serializable {


@EJB
    private ItemFacade itemFacade;

    public List<Item>  getNextItems(int maxResults, int firstResult) { 
       return itemFacade.findRange(maxResults, firstResult);    
   }


EJB 3.1 No-interface local client View

With EJB 3.1, local EJBs  do not  have to a implement separate interface, that is, all public methods of the bean class are automatically exposed to the caller.

Simplified Packaging

With Java EE 6, EJBs can be directly packaged in a WAR file just like web components.

The ItemFacade EJB uses the Java Persistence API EntityManager Query object to return a list of items. The ItemFacade EJB annotates the field private EntityManager em;  with @PersistenceContext , which causes an entity manager to be injected when it is instatiated.

Code Sample from: ItemFacade.java

@Stateless
public class ItemFacade {


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

    public List<Item> findRange(int maxResults, int firstResult) {
Query q = em.createQuery("select object(o) from Item as o");
        q.setMaxResults(maxResults);
        q.setFirstResult(firstResult);
        return q.getResultList();
    }


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 Integer id;

    private String name;   
    private String description;   
    private String imageurl;   
    private String imagethumburl; 
    private BigDecimal price;
@ManyToOne
    private Address address;
@ManyToOne
    private Product product;


    public Item() { }

    public String getName() {
        return name;
    }

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


    ...
}   




The Catalog ManagedBean pages through the list of Items by maintaining the PagingInfo.firstItem and PagingInfo.batchSize attributes and passing these as parameters to the  getNextItems(firstItem, batchSize) method. The catalog's scope  is defined with the annotation @SessionScoped, 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.


A JSF commandButton is  used to provide a button to click on to display the next page of items.  The commandButton tag is used to submit an action event to the application. 

Code Sample from: list.xhtml

 <h:commandButton action="#{catalog.next}" value="#{msgs.Next}" />   


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

Code Sample from: catalog.java

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


JSF 2.0 Simplified Navigation


The JavaServer Faces 2.0  NavigationHandler convention adds .xhtml to the logical outcome of the action method (in this example list) and loads that file, in this case, it loads the list.xhtml page after this method returns. If the action doesn't begin with a forward slash (/), JSF assumes that it's a relative path.  You can specify an absolute path by adding the slash like this "/items/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 catalog showDetail() method:

Code Sample from: list.xhtml

   <h:column>
       <f:facet name="header">
          <h:outputText value="Name"/>
       </f:facet>
       <h:commandLink action="#{catalog.showDetail(row)}" value="#{row.name}"/>   
   </h:column>


With JSF 2.0 you can now specify parameters in method expressions. The dataTable row object associated with the selected link is passed as a parameter in the  "#{catalog.showDetail(row)}" method expression.
The Catalog showDetail() method  gets the item data from the input parameter, and returns a string which causes the detail.xhtml page to display the item details :

Code Sample from: Catalog.java

    public String showDetail(Item item) {
        this.item = item;
        return "detail";
    }


The JavaServer Faces NavigationHandler adds .xhtml to the logical outcome of the action, detail and loads that file. In this case, the JavaServer Faces implementation loads the detail.xhtml page after this method returns.

The detail.xhtml uses the outputText component to display the catalog ManagedBean's item properties:

Code Sample from: detail.xhtml

    <h:outputText value="#{catalog.item.name}" title="Name" />
    <h:outputText value="#{catalog.item.description}" title="Description"/>
    <h:graphicImage library="images" name="#{catalog.item.imageurl}" title="Imageurl" />

    <h:outputText value="#{
catalog.item.price}" title="Price" />
    <h:outputText value="#{
catalog.item.address.city}" title="Address" />
    <h:outputText value="#{
catalog.item.contactinfo.email}" title="Address"/>  





GlassFish v3 is a lightweight server

  • OSGi-based; Embedded API; RESTful admin API; Lightweight and fast startup;
  • iterative development cycle "edit-save-refresh browser":
    • Incremental compile of all JSF 2.0 artifacts when you save.
    • Auto-deploy of all web or Java EE 6 artifacts
  • Session retention: maintain sessions across re-deployments


Conclusion
This concludes the sample application which demonstrates a pet catalog web application which uses Java EE 6, GlassFish v3 and MySQL.

Running the Sample Application

  1. Download and install NetBeans IDE 6.8 M1 with GlassFish v3 b57 (Glassfish v3 preview is Java EE 6 Preview) , and MySQL Community Server .
  2. Follow these instructions to set up a  jdbc-driver for MySQL. (Normally this is already setup with Glassfish, but I got an errror message with Glassfish v3 b57 that it was missing)
  3. Download the sample code. Unzip the catalog.zip file which you downloaded, this will create a catalog directory with the project code.

Create the Pet Catalog database

In order to run the sample code you first have to create the Pet Catalog database and fill in  the Item table.

  1. Start NetBeans IDE
  2. Ensure that GlassFish is registered in the NetBeans IDE, as follows:
    • Click the Services tab in the NetBeans IDE.
    • Expand the Servers node. You should see GlassFish v2 in the list of servers. If not, register GlassFish v2 as follows:
      • Right-click the Servers node and select Add Server. This opens an Add Server Instance wizard.
      • Select GlassFish v2 in the server list of the wizard and click the Next button.
      • Enter the location information for the server and click the Next button.
      • Enter the admin name and password and click the Finish button.
  3. Start the MySQL or Java DB database as follows:
    • Click the Services tab in the NetBeans IDE.
    • Expand the databases node. You should see the Java DB database in the list of databases. If you have installed the MySQL server database, you should also see the MySQL database in the list of databases.. Note:  Java DB  comes bundled with Netbeans, you can  download MySQL separately.

    • Right-mouse click on the Java DB or MySQL server database and select Start.
  4. If you installed MySQL, set the properties of the MySQL server database as follows:
    • Right-click on the MySQL server database and select Properties. This opens the MySQL Server Properties dialog box, as shown in Figure 8.

      MySQL Server Basic Properties
      Figure 8. MySQL Server Basic Properties

    • In the Basic Properties tab, enter the server host name and port number. The IDE specifies localhost as the default server host name and 3306 as the default server port number.
    • Enter the administrator user name, if not displayed, and the administrator password -- the default administrator password is blank.
    • Click the Admin Properties tab.
    • Enter an appropriate path in the Path/URL to admin tool field. You can find the path by browsing to the location of a MySQL Administration application such as the MySQL Admin Tool.
    • Enter an appropriate path in the Path to start command. You can find the path by browsing to the location of the MySQL start command. To find the start command, look for mysqld in the bin folder of the MySQL installation directory.
    • Enter an appropriate path in the Path to stop command field. You can find the path by browsing to the location of the MySQL stop command. This is usually the path to mysqladmin in the bin folder of the MySQL installation directory. If the command is mysqladmin, in the Arguments field, type -u root stop to grant root permissions for stopping the server. The Admin Properties tab should look similar to Figure 9.

      MySQL Server Administration Properties
      Figure 9. MySQL Server Administration Properties

    • Click the OK button.

  5. Right-click on the MySQL server or Java DB database and select Start.
  6. Create the petcatalog database as follows:
    • Right-mouse click on the Java DB or MySQL server database and select Create Database. This will open a create Database window.
    • Enter the database name catalog for Java DB or petcatalog for MySQL.


      For Java DB enter userid password app app as shown below:


       Click O.K. to accept the displayed settings.
  7. Create the tables in the catalog database as follows:
    • Underneath Databases you should see a database connection for the petcatalog database. For example MySQL:

      or Java DB:

    • Right-mouse click on the petcatalog connection and select Connect.
    • Right-mouse click on the petcatalog connection and select Execute Command. This will open up a SQL command window.
    • Copy the contents of the catalog.sql file in the catalog directory and paste the contents into the SQL command window, as shown in below:

      Creating Tables in the Database
    • Click the Run SQL icon Run SQL icon (Ctrl+Shift+E) above the SQL command window.
    • Note: It is ok to see this: "Error code -1, SQL state 42Y55: 'DROP TABLE' cannot be performed on 'ITEM' because it does not exist. Line 2, column 1" . This just means you are deleting a table that does not exist.  If you need to delete and recreate the tables you will not  see this message the second time.
  8. View the data in the Pet Catalog database Item table as follows:
    • Underneath Databases you should see a database connection for the petcatalog database. For example MySQL:

      or Java DB:

    • If the database connection is broken like in the following diagram:

      • Right-mouse click on the petcatalog connection and select Connect. as shown below:

      • if prompted for a password, for MySQL leave it blank, for JavaDB enter user app password app.
    • Expand the Tables node below the petcatalog database in the Services window. You should see the item table under the Tables node. You can expand the item table node to see the table columns, indexes, and any foreign keys, as shown in below :
      An Expanded Table Node
      Figure 12. An Expanded Table Node

      You can view the contents of a table or column by right-clicking the table or column and selecting View Data as shown  below:

      Viewing the Contents of a Table
      Figure 13. Viewing the Contents of a Table


  9. Follow these instructions to Create a JDBC Connection pool and JDBC resource. Name the  pool mysql_petcatalog_rootPool and the jndi resource jdbc/petcatalog. Note: you do not have to create a JDBC connection pool and resource if you use the Netbeans wizard to generate JPA entities from database tables as described in this article GlassFish and MySQL, Part 2: Building a CRUD Web Application With Data Persistence.
  10. Open the catalog/setup/sun-resources.xml file and verify that the property values it specifies match those of the petcatalog database and jdbc resources you created. Edit the property values as necessary.

Running the Sample solution:

If you want to run the sample solution, you have to create the catalog database tables first as described above.

  1. Open the catalog project as follows:
    • In NetBeans IDE, click Open Project in the File menu. This opens the Open Project dialog.
    • Navigate in the Open Project dialog to the catalog  directory and click the Open Project button.

    In response, the IDE opens the catalog project.  You can view the logical structure of the project in the Projects window (Ctrl-1).
  2. Run the catalog by right-clicking on the catalog project in the Projects window and selecting Run Project. The NetBeans IDE compiles the application, deploys it on Glassfish, and brings up the default page in your browser.  (at http://localhost:8080/catalog/).

For more information see the following resources:



Thursday Jul 30, 2009

JPA 2.0 Concurrency and locking

Optimistic Concurrency


Optimistic locking lets concurrent transactions process simultaneously, but detects and prevent collisions, this works best for applications where most concurrent transactions do not conflict. JPA Optimistic locking allows anyone to read and update an entity, however a version check is made upon commit and an exception is thrown if the version was updated in the database since the entity was read.  In JPA for Optimistic locking you annotate an attribute with @Version as shown below:

public class Employee {
    @ID int id;
@Version int version;

The Version attribute will be incremented with a successful commit. The Version attribute can be an int, short, long, or timestamp.  This results in SQL like the following:

“UPDATE Employee SET ..., version = version + 1
     WHERE id = ? AND version = readVersion

The advantages of optimistic locking are that no database locks are held which can give better scalability. The disadvantages are that the user or application must refresh and retry failed updates.

Optimistic Locking Example


In the optimistic locking example below, 2 concurrent transactions are updating employee e1. The transaction on the left commits first causing the e1 version attribute to be incremented with the update. The transaction on the right throws an OptimisticLockException because the e1 version attribute is higher than when e1 was read, causing the transaction to roll back.
img60.jpg

Additional Locking with JPA Entity Locking APIs


With JPA it is possible to lock an entity, this allows you to control when, where and which kind of locking to use. JPA 1.0 only supported Optimistic read or Optimistic write locking.  JPA 2.0 supports Optimistic and Pessimistic locking, this is layered on top of @Version checking described above.

JPA 2.0 LockMode values :
  • OPTIMISTIC (JPA 1.0 READ):
    • perform a version check on locked Entity before commit, throw an OptimisticLockException if Entity version mismatch.
  • OPTIMISTIC_FORCE_INCREMENT (JPA 1.0 WRITE)
    • perform a version check on locked Entity before commit, throw an OptimisticLockException if Entity version mismatch, force an increment to the version at the end of the transaction, even if the entity is not modified.
  • PESSIMISTIC:
    • lock the database row when reading
  • PESSIMISTIC_FORCE_INCREMENT
    • lock the database row when reading, force an increment to the version at the end of the transaction, even if the entity is not modified.
There are multiple APIs to specify locking an Entity:
  • EntityManager methods: lock, find, refresh
  • Query methods: setLockMode 
  • NamedQuery annotation: lockMode element

OPTIMISTIC (READ) LockMode Example


In the optimistic locking example below,  transaction1 on the left updates the department name for dep , which causes dep's version attribute to be incremented. Transaction2 on the right gives an employee a raise if he's in the "Eng" department. Version checking on the employee attribute would not throw an exception in this example since it was the dep Version attribute that was updated in transaction1. In this example the employee change should not commit if the department was changed after reading, so an OPTIMISTIC lock is used : em.lock(dep, OPTIMISTIC).  This will cause a version check on the  dep Entity before committing transaction2  which will throw an OptimisticLockException because the dep version attribute is higher than when dep was read, causing the transaction to roll back.
img62.jpg

OPTIMISTIC_FORCE_INCREMENT (write) LockMode Example


In the OPTIMISTIC_FORCE_INCREMENT locking example below,  transaction2 on the right wants to be sure that the dep name does not change during the transaction, so transaction2 locks the dep Entity em.lock(dep, OPTIMISTIC_FORCE_INCREMENT) and then calls em.flush() which causes dep's version attribute to be incremented in the database. This will cause any parallel updates to dep  to throw an OptimisticLockException and roll back. In transaction1 on the left at commit time when the dep version attribute is checked and found to be stale, an OptimisticLockException is thrown
img63.jpg

Pessimistic Concurrency

Pessimistic concurrency locks the database row when data is read, this is the equivalent of a (SELECT . . . FOR UPDATE [NOWAIT]) .  Pessimistic locking ensures that transactions do not update the same entity at the same time, which can simplify application code, but it limits concurrent access to the data which can cause bad scalability and may cause deadlocks. Pessimistic locking is better for applications with a higher risk of contention among concurrent transactions.
The examples below show:
  1. reading an entity and then locking it later
  2. reading an entity with a lock
  3. reading an entity, then later refreshing it with a lock

The Trade-offs are the longer you hold the lock the greater the risks of bad scalability and deadlocks. The later you lock the greater the risk of stale data, which can then cause an optimistic lock exception, if the entity was updated after reading but before locking.
img66.jpg
img672.jpg
The right locking approach depends on your application:
  • what is the risk of risk of contention among concurrent transactions?
  • What are the requirements for scalability?
  • What are the requirements for user re-trying on failure?

References and More Information:

Preventing Non-Repeatable Reads in JPA Using EclipseLink
Java Persistence API 2.0: What's New ?
What's New and Exciting in JPA 2.0
Beginning Java™ EE 6 Platform with GlassFish™ 3
Pro EJB 3: Java Persistence API (JPA 1.0)

Java Persistence API: Best Practices and Tips





Tuesday Sep 30, 2008

Sleepless in Brazil


Since September 24th I've been speaking in Brazil at JUGs, Universitys, and at Sun Tech Days as part of the September Month of Java in Brazil .

MapBRAZIL-Cities2.jpg


I spoke on September 24  in Maringa to ~500 JUG members/students/professors, September 25 in Toledo to ~ 500,  September 26 in  Xanxere to ~ 200, September 27 in Porto Alegre to ~70, and in Sao Paulo there were ~1000 attendees.   We spoke in a different location each evening which meant going to sleep late and waking up early the next morning to travel to the next location.  The guys organizing this obviously do not value sleep and time to run (I'm a avid runner)  as much as I do !   They also don't have the same conception of safety, our driver was going 90mph on a 2 lane road with oncoming traffic which didn't phase Bruno and Eduardo, whereas I was seriously praying to God for my life !! :)  The attendees in each city were very friendly and enthusiastic which compensated for the difficult schedule  (but next time I will insist on more time to travel between destinations!) .   Also we drove close to the beautiful  Iguaçu_Falls  and we flew through the beautiful Florianópolis  (note to self,  next time make sure to schedule a little time to rest and see noteworthy sites ;) .

During this trip I spoke on:

I learned a little about Brazil in conversations over dinner:
It was good that USA kicked out the Brits before we discovered gold, because the Portuguese took away a lot of Brazil's gold. USA has probably had more economic stability (until recently) because we always had a strong middle class, whereas in Brazil historically there was a big gap between the rich and poor with the wealth concentrated in a small percent of the population, however this has been improving recently
Brazil had really bad inflation during the 1970s, ~ 25% per month !  Brazillians told me they used to take their salary check and buy food for the whole month the same day.  But now the Brazillian inflation is under control, they paid off their debt,  and the economy is doing well. Last year they received more foreign investment than any other country.  
Last year Brazil made a huge oil discovery  which could raise Brazil's petroleum reserves by ~40 percent and boost Brazil into the ranks of the world's major exporters (drill baby drill) .  Brazillian cars are required to run on a gas ethanol  mixture and they have a very cost-effective process to produce ethanol from sugar cane. Brazil's sugar cane-based industry is far more efficient than the U.S. corn-based industry. Sugar cane ethanol has an energy balance 7 times greater than ethanol produced from corn , and Brazil's sugar cane based ethanol industry has not caused food prices to increase.
Bruno told me that he grew up near the amazon forest and used to swim in rivers with piranhas,  he said they don't bite unless you have a cut and are bleeding, can you imagine swimming with these things ?
piran.jpg

Here are some photos from my trip :

IMG_0868_1_1.JPG IMG_0871_1_1.JPGIMG_0878_1_1.JPG IMG_0885_1_1.JPGIMG_0886_1_1.JPG IMG_0888_1_1.JPG



Thursday Aug 07, 2008

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

Code Sample from:  List.jsp

<h:dataTable value='#{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 attribute of the CatalogBean class:


Code Sample from: CatalogBean.java

@Stateful

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

public class CatalogBean implements Serializable, Catalog {

@DataModel
    private List<Item> items=null;

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




The @DataModel Seam 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 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.  In this case, the DataModel is made available in a session context variable named items.

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 @Factory method 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 items value.

The @Name Seam annotation specifies catalog as the application unique component name which Seam will use to resolve references to the catalog context 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 @Scope Seam annotation. The CatalogBean is a org.jboss.seam.ScopeType.SESSION scoped 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:dataTable value='#{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 each column 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 CatalogBean Session EJB uses the Java Persistence API Query object to return a list of items. With the @PersistenceContext annotation 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 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
@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 @Name seam annotation specifies the (application unique) component name item, which is used in the  Detail.jsp to display the selected item's attributes. The @Scope Seam annotation binds the item instance to the org.jboss.seam.ScopeType.EVENT context.

The CatalogBean pages through the list of items by maintaining the firstItem and batchSize attributes and passing these as parameters to the query.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 CatalogBean itemCount property 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 CatalogBean getItemCount() method uses the JPA javax.persistence.Query interface 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 action event to the application. 

Code Sample from: List.jsp

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


This commandLink action attribute 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 CatalogBean next() 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 NavigationHandler matches the logical outcome,  item_list against 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 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 commandLink is  used to provide a link to click on to display the previous page of items. This commandLink action attribute  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:commandLink action="#{catalog.prev}" value="Previous #{catalog.batchSize}"   
        rendered="#{catalog.firstItem >=catalog.batchSize}"/>


 This CatalogBean prev() 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 @DataModelSelection with the @DataModel annotation, when the user clicks on the link, Seam will propagate the selected row from the DataModel into the annotated attribute:

Code Sample from: CatalogBean.java

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

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



The @DataModelSelection Seam annotation tells Seam to inject the DataModel List element corresponding to the clicked link into the item attribute.  The @Out Seam annotation transfers the value of this attribute to the item event context variable, making it available to a JSP page after the action catalog.select method execution. So when a row of the dataTable is selected, the selected row is injected to the item attribute of the CatalogBean Stateful bean, and then outjected to the event context variable named item which 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 NavigationHandler matches the logical outcome,  item_detail against 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 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 outputText component to display the item properties:

Code Sample from:  Detail.jsp

    <h:outputText value="#{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 use Seam 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 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:




About

caroljmcdonald

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today