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.
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
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 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
items property of a managed bean
that has the managed bean name
itemController.
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.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 |
package controller;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("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;
}
|
@Component is
a
Spring 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.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
dataTable
column
component, which displays a table column:
Code Sample from: List.jsp
|
<h:dataTable value='#{itemController.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 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
ItemController
getItems()
, ( 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 CatalogDAO
implements CatalogService
{
...
|
The
The Spring IoC
container will inject the
catalogService
Spring Bean
into the
catalogService
property
of the
ItemController
JSF
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 to
inject
dependencies that match by type. The
setCatalogService
is 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
CatalogDAO uses
an
EntityManager
Query 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
@PersistenceContext
annotation. 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 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 createQuery method creates an instance of a Query
class for executing a Java Persistence query language statement. The setMaxResults()
method in Query 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 for Item,
you'll see that it meets the two requirements for an entity:
- The class is annotated with an
@Entity annotation.
- 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 Address
address;
@ManyToOne
private Product
product;
public Item() { }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
...
}
|
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, which gets the items for display in the table of
pets.
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;
}
|
Displaying the Next List of items
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}"/>
|
This
commandLink action
attribute
references the
ItemController
backing 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
ItemController
next
method 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
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>
|
When the
List.jsp dataTable is rendered, the
value binding
causes the
ItemController
getItems method
to be called, as discussed before, which will cause the next list of
items to be displayed.
Code Sample from: List.jsp
|
<h:dataTable value='#{itemController.items}' var='dataTableItem'
border="1" cellpadding="2" cellspacing="0">
|
Displaying an Item's Details
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
ItemController
detailSetup()
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
ItemController
detailSetup()
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
NavigationHandler
matches the logical outcome,
item_detail
against 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
outputText
component to display the
ItemController
ManagedBean's
item
properties:
| Code Sample from: detail.jsp |
<h:outputText
value="#{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="#{itemController.item.address.city}"
title="Address" />
<h:outputText value="#{itemController.item.contactinfo.email}"
title="Address"/>
|
Conclusion
This concludes the sample application which demonstrates how to work
with the
JSF
dataTable and
DataModel
to page through a list
of
Item
Entities
which 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)
- Download
and install NetBeans 6.1 . Get the full distribution with Java EE and
Glassfish v2.
- 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.
- Open the Admin Console of the GlassFish V2 application server in
order to create the JDBC
Connection pool and JDBC resource:
- Select the NetBeans Services
tab
window.
- Expand Servers.
- Right click GlassFish V2
and select View Admin Console.
- Enter values to User Name
and Password fields - the
default is admin for User
Name
and adminadmin for the
Password
- Create a connection pool using the Admin Console:
- Expand Resources->JDBC.
- Click Connection Pools.
- Click New on the
right
of the page.
- For the Name field,
enter PETCatalogPool.
- For Resource Type,
select javax.sql.DataSource
from the drop-down
menu.
- For Database Vendor field, select JavaDB from the drop-down menu.
- Click Next.
- Scroll down to the end of the page to see the Additional Properties section.
- For Connection Attributes
field, enter
;create=true.
- For DatabaseName
field,
enter pet-catalog.
- For Password field,
enter app.
- For User field,
enter app.
- Click Finish.
- Remove the SecurityMechanism property
from the PETCatalogPool:.
- Select PetCatalogPool under
Connection Pools
node
on
the left.
- Select Additional
Properties
tab on the right and observe that the Edit
Connection Pool Properties are displayed.
- Check Security Mechanism
and click Delete Properties.Click
Save.
- Start the Java DB server using NetBeans:
- Select Tools from
the
NetBeans
top-level menu
bar and select Java DB
Database->Start Server.
- Make sure the PetCatalogPool is
operational using the Admin Console:
- Start the Java DB server (if it is not started already)
- Select the Admin Console General
tab
window.
- Click Ping button.
- Make sure that the Ping
Succeeded message is displayed on the top.
- Create a JDBC resource using the Admin Console:
- Select JDBC Resources
under JDBC on the left of the
Admin Console .
- Click New button on
the
right.
- For JNDI Name field,
enter jdbc/PETCatalogDB.
- For Pool Name field,
select PETCatalogPool from the
drop-down menu.
- Click OK.
- Create a Database connection using NetBeans:
- Select the NetBeans Services tab window.
- Right click Database and select New Connection.
- Observe that the New
Database
Connection dialog box appears.
- For the Database URL field, enter jdbc:derby://localhost:1527/pet-catalog.
- For User Name field, enter app.
- For Password field, enter app.
- Click OK.
- Create a database using NetBeans:
Select Tools from the
NetBeans top-level menu bar and select Java
DB
Database->Create Database.
- Observe that the Create Java DB Database dialog appears.
- For the Database Name field, enter pet-catalog.
- For User Name field, enter app.
- For Password field, enter app.
- Click OK.
- Populate the database tables in the pet-catalog database as
follows:
- Under Databases, select the connection pet-catalog that you
just created.
- Right mouse click on pet-catalog and select Excecute Command.
- In the SQL command window copy paste all the sql text from
the file
<sample_install_dir>/SpringJPA/setup/sql/javadb/catalog.sql,
- 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:
- 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.
- Start the NetBeans IDE. Click Open Project in the File menu and
select the
SpringJPA directory you just unzipped.
- 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.
- 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.
- Build the project as follows:
- Right click the
SpringJPA node in the Projects
window.
- Select Clean and Build Project.
- 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 :
- If you want to create your own application, Create a new
Netbeans Web Application:
- 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 .
- on the frameworks window select Spring Framework 2.5, click
Finish.
- 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)
- Configuration of
the XML files for Spring 2.5, JSF, and JPA, running on Glassfish.
For Spring configuration modify the applicationConfiguration.xml
and modify the web.xml
and faces-config.xml
as described below.
- modify the file /WEB-INF/applicationContext.xml
to the war WEB-INF
directory. 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>
|
- 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 Faces,
Advanced
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>
|
- Add the
SpringBeanFacesELResolver to
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: