Interacting with Databases through the Java Persistence API

Exclusive offer: get 50% off this eBook here
Java EE 5 Development with NetBeans 6

Java EE 5 Development with NetBeans 6 — Save 50%

Develop professional enterprise Java EE applications quickly and easily with this popular IDE

£18.99    £9.50
by Suhreed Sarkar | November 2008 | Joomla! MySQL Content Management Open Source PHP

The Java Persistence API (JPA) is an object relational mapping API. Object relational mapping tools help us automate mapping Java objects to relational database tables. Earlier versions of J2EE used Entity Beans as the standard approach for object relational mapping. Entity Beans attempted to keep the data in memory always synchronized with database data, a good idea in theory, however, in practice this feature resulted in poorly performing applications.

Several object relational mapping APIs were developed to overcome the limitations of Entity Beans, such as Hibernate, iBatis, Cayenne, and Toplink among others.

With Java EE 5, Entity Beans were deprecated in favor of JPA. JPA took ideas from several object relational mapping tools and incorporated them into the standard. As we will see in this article by David Heffelfinger, NetBeans has several features that make development with JPA a breeze.

We will look into:

  • Creating our first JPA entity
  • Interacting with JPA entities with entity manager
  • Generating forms in JSF pages from JPA entities
  • Generating JPA entities from an existing database schema
  • JPA named queries and JPQL
  • Entity relationships
  • Generating complete JSF applications from JPA entities

Creating Our First JPA Entity

JPA entities are Java classes whose fields are persisted to a database by the JPA API. JPA entities are Plain Old Java Objects (POJOs), as such, they don't need to extend any specific parent class or implement any specific interface. A Java class is designated as a JPA entity by decorating it with the @Entity annotation.

In order to create and test our first JPA entity, we will be creating a new web application using the JavaServer Faces framework. In this example we will name our application jpaweb. As with all of our examples, we will be using the bundled GlassFish application server.

To create a new JPA Entity, we need to right-click on the project and select New | Entity Class.

Interacting with Databases through the Java Persistence API

After doing so, NetBeans presents the New Entity Class wizard.

Interacting with Databases through the Java Persistence API

At this point, we should specify the values for the Class Name and Package fields (Customer and com.ensode.jpaweb in our example), then click on the Create Persistence Unit... button.

Interacting with Databases through the Java Persistence API

The Persistence Unit Name field is used to identify the persistence unit that will be generated by the wizard, it will be defined in a JPA configuration file named persistence.xml that NetBeans will automatically generate from the Create Persistence Unit wizard. The Create Persistence Unit wizard will suggest a name for our persistence unit, in most cases the default can be safely accepted.

JPA is a specification for which several implementations exist. NetBeans supports several JPA implementations including Toplink, Hibernate, KODO, and OpenJPA. Since the bundled GlassFish application server includes Toplink as its default JPA implementation, it makes sense to take this default value for the Persistence Provider field when deploying our application to GlassFish.

Before we can interact with a database from any Java EE 5 application, a database connection pool and data source need to be created in the application server.

A database connection pool contains connection information that allow us to connect to our database, such as the server name, port, and credentials. The advantage of using a connection pool instead of directly opening a JDBC connection to a database is that database connections in a connection pool are never closed, they are simply allocated to applications as they need them. This results in performance improvements, since the operations of opening and closing database connections are expensive in terms of performance.

Data sources allow us to obtain a connection from a connection pool by obtaining an instance of javax.sql.DataSource via JNDI, then invoking its getConnection() method to obtain a database connection from a connection pool. When dealing with JPA, we don't need to directly obtain a reference to a data source, it is all done automatically by the JPA API, but we still need to indicate the data source to use in the application's Persistence Unit.

NetBeans comes with a few data sources and connection pools pre-configured. We could use one of these pre-configured resources for our application, however, NetBeans also allows creating these resources "on the fly", which is what we will be doing in our example.

To create a new data source we need to select the New Data Source... item from the Data Source combo box.

Interacting with Databases through the Java Persistence API

A data source needs to interact with a database connection pool. NetBeans comes pre-configured with a few connection pools out of the box, but just like with data sources, it allows us to create a new connection pool "on demand". In order to do this, we need to select the New Database Connection... item from the Database Connection combo box.

Interacting with Databases through the Java Persistence API

NetBeans includes JDBC drivers for a few Relational Database Management Systems (RDBMS) such as JavaDB, MySQL, and PostgreSQL "out of the box". JavaDB is bundled with both GlassFish and NetBeans, therefore we picked JavaDB for our example. This way we avoid having to install an external RDBMS.

For RDBMS systems that are not supported out of the box, we need to obtain a JDBC driver and let NetBeans know of it's location by selecting New Driver from the Name combo box. We then need to navigate to the location of a JAR file containing the JDBC driver. Consult your RDBMS documentation for details.

JavaDB is installed in our workstation, therefore the server name to use is localhost. By default, JavaDB listens to port 1527, therefore that is the port we specify in the URL. We wish to connect to a database called jpaintro, therefore we specify it as the database name. Since the jpaintro database does not exist yet, we pass the attribute create=true to JavaDB, this attribute is used to create the database if it doesn't exist yet.

Every JavaDB database contains a schema named APP, since each user by default uses a schema named after his/her own login name. The easiest way to get going is to create a user named "APP" and select a password for this user.

Clicking on the Show JDBC URL checkbox reveals the JDBC URL for the connection we are setting up.

The New Database Connection wizard warns us of potential security risks when choosing to let NetBeans remember the password for the database connection. Database passwords are scrambled (but not encrypted) and stored in an XML file under the .netbeans/[netbeans version]/config/Databases/Connections directory. If we follow common security practices such as locking our workstation when we walk away from it, the risks of having NetBeans remember database passwords will be minimal.

Once we have created our new data source and connection pool, we can continue configuring our persistence unit.

Interacting with Databases through the Java Persistence API

It is a good idea to leave the Use Java Transaction APIs checkbox checked. This will instruct our JPA implementation to use the Java Transaction API (JTA) to allow the application server to manage transactions. If we uncheck this box, we will need to manually write code to manage transactions.

Most JPA implementations allow us to define a table generation strategy. We can instruct our JPA implementation to create tables for our entities when we deploy our application, to drop the tables then regenerate them when our application is deployed, or not create any tables at all. NetBeans allows us to specify the table generation strategy for our application by clicking the appropriate value in the Table Generation Strategy radio button group.

When working with a new application, it is a good idea to select the Drop and Create table generation strategy. This will allow us to add, remove, and rename fields in our JPA entity at will without having to make the same changes in the database schema. When selecting this table generation strategy, tables in the database schema will be dropped and recreated, therefore any data previously persisted will be lost.

Once we have created our new data source, database connection and persistence unit, we are ready to create our new JPA entity.

Interacting with Databases through the Java Persistence API

We can do so by simply clicking on the Finish button. At this point NetBeans generates the source for our JPA entity.

JPA allows the primary field of a JPA entity to map to any column type (VARCHAR, NUMBER). It is best practice to have a numeric surrogate primary key, that is, a primary key that serves only as an identifier and has no business meaning in the application. Selecting the default Primary Key type of long will allow for a wide range of values to be available for the primary keys of our entities.

package com.ensode.jpaweb;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
public void setId(Long id) {
this.id = id;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
//Other generated methods (hashCode(), equals() and
//toString() omitted for brevity.
}

As we can see, a JPA entity is a standard Java object. There is no need to extend any special class or implement any special interface. What differentiates a JPA entity from other Java objects are a few JPA-specific annotations.

The @Entity annotation is used to indicate that our class is a JPA entity. Any object we want to persist to a database via JPA must be annotated with this annotation.

The @Id annotation is used to indicate what field in our JPA entity is its primary key. The primary key is a unique identifier for our entity. No two entities may have the same value for their primary key field. This annotation can be placed just above the getter method for the primary key class. This is the strategy that the NetBeans wizard follows. It is also correct to specify the annotation right above the field declaration.

The @Entity and the @Id annotations are the bare minimum two annotations that a class needs in order to be considered a JPA entity. JPA allows primary keys to be automatically generated. In order to take advantage of this functionality, the @GeneratedValue annotation can be used. As we can see, the NetBeans generated JPA entity uses this annotation. This annotation is used to indicate the strategy to use to generate primary keys. All possible primary key generation strategies are listed in the following table:

 

Primary Key Generation Strategy

 

Description

 

GenerationType.AUTO

 

Indicates that the persistence provider will automatically select a primary key generation strategy. Used by default if no primary key generation strategy is specified.

 

GenerationType.IDENTITY

 

Indicates that an identity column in the database table the JPA entity maps to must be used to generate the primary key value.

 

GenerationType.SEQUENCE

 

Indicates that a database sequence should be used to generate the entity's primary key value.

 

GenerationType.TABLE

 

Indicates that a database table should be used to generate the entity's primary key value.

 

 

 

In most cases, the GenerationType.AUTO strategy works properly, therefore it is almost always used. For this reason the New Entity Class wizard uses this strategy.

When using the sequence or table generation strategies, we might have to indicate the sequence or table used to generate the primary keys. These can be specified by using the @SequenceGenerator and @TableGenerator annotations, respectively. Consult the Java EE 5 JavaDoc at http://java.sun.com/javaee/5/docs/api/ for details.

For further knowledge on primary key generation strategies you can refer EJB 3 Developer Guide by Michael Sikora, which is another book by Packt Publishing (http://www.packtpub.com/developer-guide-for-ejb3/book).

Adding Persistent Fields to Our Entity

At this point, our JPA entity contains a single field, its primary key. Admittedly not very useful, we need to add a few fields to be persisted to the database.

package com.ensode.jpaweb;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String firstName;
private String lastName;
public void setId(Long id) {
this.id = id;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
//Additional methods omitted for brevity
}

In this modified version of our JPA entity, we added two fields to be persisted to the database; firstName will be used to store the user's first name, lastName will be used to store the user's last name. JPA entities need to follow standard JavaBean coding conventions. This means that they must have a public constructor that takes no arguments (one is automatically generated by the Java compiler if we don't specify any other constuctors), and all fields must be private, and accessed through getter and setter methods.

Automatically Generating Getters and Setters
In NetBeans, getter and setter methods can be generated automatically. Simply declare new fields as usual then use the "insert code" keyboard shortcut (default is Alt+Insert), then select Getter and Setter from the resulting pop-up window, then click on the check box next to the class name to select all fields, then click on the Generate button.

Before we can use JPA persist our entity's fields into our database, we need to write some additional code.

Creating a Data Access Object (DAO)

It is a good idea to follow the DAO design pattern whenever we write code that interacts with a database. The DAO design pattern keeps all database access functionality in DAO classes. This has the benefit of creating a clear separation of concerns, leaving other layers in our application, such as the user interface logic and the business logic, free of any persistence logic.

There is no special procedure in NetBeans to create a DAO. We simply follow the standard procedure to create a new class by selecting File | New, then selecting Java as the category and the Java Class as the file type, then entering a name and a package for the class. In our example, we will name our class CustomerDAO and place it in the com.ensode.jpaweb package.

At this point, NetBeans create a very simple class containing only the package and class declarations.

To take complete advantage of Java EE features such as dependency injection, we need to make our DAO a JSF managed bean. This can be accomplished by simply opening faces-config.xml, clicking its XML tab, then right-clicking on it and selecting JavaServer Faces | Add Managed Bean.

Interacting with Databases through the Java Persistence API

We get the Add Manged Bean dialog as seen here:

Interacting with Databases through the Java Persistence API

We need to enter a name, fully qualified name, and scope for our managed bean (which, in our case, is our DAO), then click on the Add button.

This action results in our DAO being declared as a managed bean in our application's faces-config.xml configuration file.

<managed-bean> 
<managed-bean-name>CustomerDAO</managed-bean-name>
<managed-bean-class>
com.ensode.jpaweb.CustomerDAO
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

We could at this point start writing our JPA code manually, but with NetBeans there is no need to do so, we can simply right-click on our code and select Persistence | Use Entity Manager, and most of the work is automatically done for us.

Interacting with Databases through the Java Persistence API

Here is how our code looks like after doing this trivial procedure:

package com.ensode.jpaweb;
import javax.annotation.Resource;
import javax.naming.Context;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@PersistenceContext(name = "persistence/LogicalName",
unitName = "jpawebPU")
public class CustomerDAO {
@Resource
private javax.transaction.UserTransaction utx;
protected void persist(Object object) {
try {
Context ctx =
(Context) new javax.naming.InitialContext().
lookup("java:comp/env");
utx.begin();
EntityManager em = (EntityManager)
ctx.lookup("persistence/LogicalName");
em.persist(object);
utx.commit();
} catch (Exception e) {
java.util.logging.Logger.getLogger(
getClass().getName()).log(
java.util.logging.Level.SEVERE,
"exception caught", e);
throw new RuntimeException(e);
}
}
}

All highlighted code is automatically generated by NetBeans. The main thing NetBeans does here is add a method that will automatically insert a new row in the database, effectively persisting our entity's properties.

As we can see, NetBeans automatically generates all necessary import statements. Additionally, our new class is automatically decorated with the @PersistenceContext annotation. This annotation allows us to declare that our class depends on an EntityManager (we'll discuss EntityManager in more detail shortly). The value of its name attribute is a logical name we can use when doing a JNDI lookup for our EntityManager. NetBeans by default uses persistence/LogicalName as the value for this property.

The Java Naming and Directory Interface (JNDI) is an API we can use to obtain resources, such as database connections and JMS queues, from a directory service.

The value of the unitName attribute of the @PersistenceContext annotation refers to the name we gave our application's Persistence Unit.

NetBeans also creates a new instance variable of type javax.transaction.UserTransaction. This variable is needed since all JPA code must be executed in a transaction. UserTransaction is part of the Java Transaction API (JTA). This API allows us to write code that is transactional in nature. Notice that the UserTransaction instance variable is decorated with the @Resource annotation. This annotation is used for dependency injection. in this case an instance of a class of type javax.transaction.UserTransaction will be instantiated automatically at run-time, without having to do a JNDI lookup or explicitly instantiating the class.

Dependency injection is a new feature of Java EE 5 not present in previous versions of J2EE, but that was available and made popular in the Spring framework. With standard J2EE code, it was necessary to write boilerplate JNDI lookup code very frequently in order to obtain resources. To alleviate this situation, Java EE 5 made dependency injection part of the standard.

The next thing we see is that NetBeans added a persist method that will persist a JPA entity, automatically inserting a new row containing our entity's fields into the database. As we can see, this method takes an instance of java.lang.Object as its single parameter. The reason for this is that the method can be used to persist any JPA entity (although in our example, we will use it to persist only instances of our Customer entity).

The first thing the generated method does is obtain an instance of javax.naming.InitialContext by doing a JNDI lookup on java:comp/env. This JNDI name is the root context for all Java EE 5 components.

The next thing the method does is initiate a transaction by invoking uxt.begin(). Notice that since the value of the utx instance variable was injected via dependency injection (by simply decorating its declaration with the @Resource annotation), there is no need to initialize this variable.

Next, the method does a JNDI lookup to obtain an instance of javax.persistence.EntityManager. This class contains a number of methods to interact with the database. Notice that the JNDI name used to obtain an EntityManager matches the value of the name attribute of the @PersistenceContext annotation.

Once an instance of EntityManager is obtained from the JNDI lookup, we persist our entity's properties by simply invoking the persist() method on it, passing the entity as a parameter to this method. At this point, the data in our JPA entity is inserted into the database.

In order for our database insert to take effect, we must commit our transaction, which is done by invoking utx.commit().

It is always a good idea to look for exceptions when dealing with JPA code. The generated method does this, and if an exception is caught, it is logged and a RuntimeException is thrown. Throwing a RuntimeException has the effect of rolling back our transaction automatically, while letting the invoking code know that something went wrong in our method. The UserTransaction class has a rollback() method that we can use to roll back our transaction without having to throw a RunTimeException.

At this point we have all the code we need to persist our entity's properties in the database. Now we need to write some additional code for the user interface part of our application. NetBeans can generate a rudimentary JSF page that will help us with this task.

Java EE 5 Development with NetBeans 6 Develop professional enterprise Java EE applications quickly and easily with this popular IDE
Published: October 2008
eBook Price: £18.99
Book Price: £30.99
See more
Select your format and quantity:

Generating the User Interface

To have NetBeans automatically generate the user interface, first we need to create a new JSP as usual, by right-clicking on the project, selecting New | JSP, then entering a name for our JSP in the New JSP File wizard. At this point, the generated markup for the new JSP will look like this:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>

Once we have our JSP, we can drag the JSF Form element from the NetBeans palette into our markup, then select Form Generated From Entity Class, enter the fully qualified name for our JPA entity, then select Editable in the Form Fields radio buttons.

Interacting with Databases through the Java Persistence API

After adding the generated markup, we need to manually add the standard JSF <%@ taglib%> elements to our page. After modifying the generated title and deleting the  and deleting the <h2> tag generated by the New JSP File wizard, our page markup now looks like this:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert Customer</title>
</head>
<body>
<f:view>
<h2>Create</h2>
<h:form>
<h:panelGrid columns="2">
<h:outputText value="FirstName:"/>
<h:inputText id="firstName"
value="#{anInstanceOfcom.ensode.jpaweb.Customer. firstName}"
title="FirstName" />
<h:outputText value="LastName:"/>
<h:inputText id="lastName" value="#{anInstanceOfcom.ensode.jpaweb. Customer.lastName}"
title="LastName" />
</h:panelGrid>
</h:form>
</f:view>
</body>
</html>

Notice that NetBeans automatically inserts JSF complete with value binding expressions mapping to our entity's properties. It uses a temporary placeholder managed bean name to access our entity. In our example, the generated managed bean name is anInstanceOfcom.ensode.jpaweb.Customer. In general, the generated managed bean name will be the fully qualified name of the bean's class, prefixed by anInstanceOf. Before this code can work, we need to make our JPA entity a JSF managed bean following the same procedure we used for the DAO.

In order to be able to persist the user-entered data, we need to make a few modifications to the generated markup in our JSP.

<h:form> 
<h:panelGrid columns="2">
<h:outputText value="FirstName:"/>
<h:inputText id="firstName"
value="#{Customer.firstName}" title="FirstName" />
<h:outputText value="LastName:"/>
<h:inputText id="lastName" value="#{Customer.lastName}"
title="LastName" />
<h:panelGroup/>
<h:commandButton value="Submit"
action="#{Controller.saveCustomer}"/>
</h:panelGrid>
</h:form>

The first thing we need to do is modify the value binding expression of the generated <h:inputText> elements to match the name we gave our JPA entity in faces-config.xml (Customer, in our case), then we need to add a command button so that our page will be submitted.

Implementing the Controller

At this point, we have the presentation layer (View) of our application ready, as well as the data access layer (Model), the only thing missing is to add a controller to complete the third layer of our application, which will follow the MVC design pattern.

package com.ensode.jpaweb;
public class Controller {
private CustomerDAO customerDAO;
private Customer customer;
public CustomerDAO getCustomerDAO() {
return customerDAO;
}
public void setCustomerDAO(CustomerDAO customerDAO) {
this.customerDAO = customerDAO;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public String saveCustomer() {
String returnVal;
try {
customerDAO.persist(customer);
returnVal = "success";
} catch (Exception e) {
returnVal = "failure";
e.printStackTrace();
}
System.out.println(this.getClass().getName() + ".saveCustomer()nreturnVal = " + returnVal);
return returnVal;
}
}

Our controller has a saveCustomer() method that will be invoked when the user clicks on the Submit button on the page, the method simply invokes the persist() method on the DAO, then uses standard JSF navigation to go to a confirmation page if everything went fine, or to an error page if an exception was thrown.

Notice the Controller class has two instance variables for our JPA entity and our DAO. There is no need for us to explicitly instantiate these variables, instead we can use a JSF feature called managed properties. Managed properties are injected at runtime by using dependency injection. In order to configure this the application's faces-config.xml needs to be modified.

<managed-bean> 
<managed-bean-name>CustomerDAO</managed-bean-name>
<managed-bean-class>
com.ensode.jpaweb.CustomerDAO
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>Customer</managed-bean-name>
<managed-bean-class>
com.ensode.jpaweb.Customer
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>Controller</managed-bean-name>
<managed-bean-class>
com.ensode.jpaweb.Controller
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>customerDAO</property-name>
<property-class>
com.ensode.jpaweb.CustomerDAO
</property-class>
<value>#{CustomerDAO}</value>
</managed-property>
<managed-property>
<property-name>customer</property-name>
<property-class>
com.ensode.jpaweb.Customer
</property-class>
<value>#{Customer}</value>
</managed-property>
</managed-bean>

The <managed-property> element is used to define our managed properties. The <property-name> element is used to indicate the managed property name; the value of this element must match the name of the property in the managed bean's code (in our example, both the customer and customerDAO properties are managed properties). The value of the <property-class> element must be the fully qualified name of the property type, and the value of the <value> attribute must match the value of the <managed-bean-name> element for managed beans used to populate managed properties. In our example, our JPA entity is declared as a managed bean, using a value of Customer as its logical name, which matches the value binding expression of #{Customer} used to populate the customer managed property of our controller. In order to have the customerDAO property populated at runtime, our CustomerDAO class needs to be added as a managed bean like we previously did for the Customer class.

Trying Out Our Application

At this point, we have a complete, albeit simple, application that will gather input from the user, populate a JPA entity from this input, and save the data to the database. We can execute our application by right-clicking on the project and selecting Run.

At this point the application server is started if it wasn't running already, our application is deployed and a new window of the default web browser is automatically opened, pointing to the URL of our application. After entering some data into the input fields, our page looks like:

Interacting with Databases through the Java Persistence API

Notice that the labels for the fields aren't very user-friendly. Recall that this page was almost completely generated from our JPA entity bean. By default, NetBeans uses the property name as the label for each field. We are free, of course, to modify these labels to make them more readable for our users.

After clicking the Submit button, our data is saved to the database and we are directed to a confirmation screen.

Interacting with Databases through the Java Persistence API

If we inspect our database schema, we can see that a CUSTOMER table was created automatically, since we used the Drop and Create Table generation strategy. Additionally, a new row was inserted when we clicked on the Submit button.

We can inspect the database schema by going to the Services tab, right-clicking on our schema (jpaintro), then selecting Connect. Expanding the Tables node reveals the newly created CUSTOMER.

Interacting with Databases through the Java Persistence API

We can view the data in the table by right-clicking on it and selecting View Data. At this point a new SQL Command window is opened and an SQL query retrieving all the data in our table is automatically executed.

Interacting with Databases through the Java Persistence API

As we have seen, NetBeans makes it easy to write code that inserts rows into a database table by generating JPA code.

If we need to add additional functionality such as retrieving, updating, or deleting data, we would need to write additional methods in our DAO. The DAO would invoke corresponding methods on EntityManager. The following table lists some of the most commonly used methods on EntityManager.

 

EntityManager method

 

Description

 

Example

 

<T> T find(Class<T> entityClass, Object primaryKey)

 

Retrieves a row of data matching the supplied primary key from the database table our JPA entity maps to. The first parameter must be the class of our JPA entity, the second parameter must be the primary key.

 

customer = em.find(Customer.class, new Long(2));

 

<T> T merge(T entity)

 

Updates the data in the database with the values contained in the JPA entity's properties.

 

em.merge(customer);

 

remove(Object entity)

 

Deletes the row corresponding to the JPA entity from the database table the entity maps to.

 

em.remove(customer);

 

 

 

Just like the persist() method, the methods listed on the above table must be invoked inside a transaction, therefore a DAO's method invoking the above EntityManger methods should follow the pattern in our DAO's persist() method (lookup EntityManager, begin a transaction, invoke the method, commit the transaction, look for any exceptions and throw a RuntimeException to roll back the transaction, if necessary).

If we are working with a JSF application, such as in our example, we would need to write additional methods on our Controller managed bean that would invoke DAO methods whenever a user submits a form. Additionally we would have to write additional JSP pages to create the user interface.

As we will see later in this article, NetBeans can automate most of the steps described in the previous two paragraphs. But before we get there, we will discuss one great feature of NetBeans: automated generation of JPA entities from an existing database schema.

Automated Generation of JPA Entities

In the previous section, we saw how we can automatically create database tables from JPA entities. This is an optional feature of the JPA specification, however most JPA implementations implement it. One feature that is not available from JPA is the converse, generating JPA entities from database tables. Luckily for us, NetBeans provides this functionality.

In this section, we will be using a custom database schema. In order to create the schema, we need to execute an SQL script that will create the schema and populate some of its tables. To do this, we need to go to the Services window, right-click on JavaDB, then select Create Database....

Interacting with Databases through the Java Persistence API

We then need to add the database information in the Create Java DB Database wizard.

Interacting with Databases through the Java Persistence API

At this point, we can open the SQL script by going to File | Open File..., then navigating to its location on our disk and opening it.

The file name of our script is create_populate_tables.sql.

Interacting with Databases through the Java Persistence API

Once we have opened the SQL script, we need to select our newly created connection from the Connection combo box, then click on the icon to execute it. Our database will now have a number of tables.

Interacting with Databases through the Java Persistence API

NetBeans allows us to generate JPA entities from an existing schema. To do so we need to create a new project, then right-click on the project, then select New | Entity Classes from Database....

NetBeans allows us to generate JPA entities from pretty much any kind of Java project. In our example we will be using a Web Application project.

Interacting with Databases through the Java Persistence API

We see a New Entity Classes from Database dialog as depicted here:

Interacting with Databases through the Java Persistence API

At this point we can either select an existing data source, or, like we did in the previous example, create one "on the fly". In our example we created a new one, then selected the database connection we created earlier in this section.

Once we have created or selected our data source, we need to select one or more tables to use to generate our JPA entities. If we wish to create JPA entities for all tables, we can simply click on the Add All>> button.

After clicking Next, NetBeans gives us the opportunity to change the names of the generated classes, although the defaults tend to be sensible. We should also specify a package for our classes, and it is a good idea to check the Generate Named Query Annotations for Persistent Fields checkbox.

Interacting with Databases through the Java Persistence API

In the next screen in the wizard, we can select how associated entities will be fetched (eagerly or lazily). By default, the default behavior is selected, which is to fetch "one-to-one" and "many-to-one" relationships eagerly, and "one-to-many" and "many-to-many" relationships lazily.

Additionally, we can select what collection type to use for the "many" side of a "one-to-many" or "many-to-many" relationship. The default value is java.util.Collection. Other valid values are java.util.List and java.util.Set.

Interacting with Databases through the Java Persistence API

Checking the Fully Qualified Database Table Names checkbox results in adding the catalog and schema elements of the table being mapped to the @Table annotation for each generated entity.

Checking the Attributes for Regenerating Tables results in the generated @Column annotations having attributes such as length, which specifies the maximum length allowed in the column; nullable, which specifies if null values are allowed in the column; precision and scale, which specify the precision and scale of decimal values, respectively. Checking this attribute also adds the uniqueConstraints attribute to the generated @Table annotation to specify any unique constraints that apply to the table, if necessary. When clicking Finish, NetBeans generates JPA entities for all tables in the database. Our database contained a table named CUSTOMER table. Let's take a look at the generated Customer JPA entity.

package com.ensode.jpa;
//Import statements removed for brevity.
@Entity
@Table(name = "CUSTOMER")
@NamedQueries({@NamedQuery(name = "Customer.findByCustomerId",
query = "SELECT c FROM Customer c WHERE c.customerId = :customerId"),@NamedQuery
(name = "Customer.findByFirstName",
query = "SELECT c FROM Customer c WHERE c.firstName = :firstName"),
@NamedQuery(name = "Customer.findByMiddleName",
query = "SELECT c FROM Customer c WHERE c.middleName = :middleName"),
@NamedQuery(name = "Customer.findByLastName",
query = "SELECT c FROM Customer c WHERE c.lastName = :lastName"),
@NamedQuery(name = "Customer.findByEmail",
query = "SELECT c FROM Customer c WHERE c.email = :email")})
public class Customer implements Serializable {
@Id
@Column(name = "CUSTOMER_ID", nullable = false)
private Integer customerId;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "MIDDLE_NAME")
private String middleName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "EMAIL")
private String email;
@OneToMany(mappedBy = "customerId")
private Collection<CustomerOrder> customerOrderCollection;
@OneToMany(mappedBy = "customerId")
private Collection<Address> addressCollection;
@OneToMany(mappedBy = "customerId")
private Collection<Telephone> telephoneCollection;
//Getters, setters and other generated methods and
//constructors removed for brevity.
}

As we can see, NetBeans generates a class decorated with the @Entity annotation, which marks the class as a JPA entity. Notice that NetBeans automatically decorated one of the fields with the @Id annotation, based on the primary key constraint in the table used to generate the JPA entity. Notice that no primary key generation strategy is used. We either need to populate the primary key ourselves, or add the @GeneratedValue annotation manually.

Also notice the @Table annotation. This is an optional annotation that indicates what table our JPA entity maps to. If the @Table annotation is not used, then our entity will map to a table having the same name as the entity class (case insensitive). In our particular example, the @Table annotation is redundant, but there are cases where it is useful. For example, some database schemas have tables named in plural (CUSTOMERS), but it makes sense to name our entities in singular (Customer). Additionally, the standard naming convention for database tables containing more than one word is to use underscores to separate words (CUSTOMER_ORDER) where in Java the standard is to use camel case (CustomerOrder). The @Table annotation allows us to follow established naming standards in both the relational database and the Java worlds.

Java EE 5 Development with NetBeans 6 Develop professional enterprise Java EE applications quickly and easily with this popular IDE
Published: October 2008
eBook Price: £18.99
Book Price: £30.99
See more
Select your format and quantity:

Named Queries and JPQL

Next, we see the @NamedQueries annotation (this annotation is only generated if we click on the Generate Named Query Annotations for Persistent Fields checkbox of the New Entity Classes from Database wizard). This query contains a value attribute (the attribute name can be omitted from the code since it is the only attribute in this annotation). The value of this attribute is an array of @NamedQuery annotations. The @NamedQuery annotation has a name attribute, which is used to give it a logical name (By convention, the JPA entity name is used as part of the query name. As we can see in the generated code, the New Entity Classes from Database wizard follows this convention), and a query attribute, which is used to define a Java Persistence Query Language (JPQL) query to be executed by the named query.

JPQL is a JPA-specific query language. Its syntax is similar to SQL. The New Entity Classes from Database wizard generates a JPQL query for each field in our entity. When the query is executed, a List containing all instances of our entity that match the criteria in the query will be returned. The following code snippet illustrates this process.

import java.util.List; 
import javax.persistence.EntityManager;
import javax.persistence.Query;
public class CustomerDAO {
public List findCustomerByLastName(String someLastName)
{
//code to lookup EntityManager omitted for brevity
Query query =
em.createNamedQuery("Customer.findByLastName");
query.setParameter("lastName", someLastName);
List resultList = query.getResultList();
return resultList;
}
}

Here we see a DAO object containing a method that will return a list of Customer entities for customers whose last name equals the one provided in the method's parameter. In order to implement this, we need to obtain an instance of an object of type javax.pesistence.Query. As we can see in the previous code snippet, this can be accomplished by invoking the createNamedQuery() method in EntityManager, passing the query name (as defined in the @NamedQuery annotation) as a parameter. Notice that the named queries generated by the NetBeans wizard contain strings preceded by a colon (:), these strings are named parameters. Named parameters are "placeholders" we can use to substitute for appropriate values.

In our example, we set the lastName named parameter in JPQL query with the someLastName argument passed to our method.

Once we have populated all parameters in our query, we can obtain a List of all matching entities by invoking the getResultList() method in our Query object.

Going back to our generated JPA entity, notice the wizard automatically placed the @Id annotation in the field mapping to the table's primary key. Additionally, each field is decorated with the @Column annotation, which allows us to follow standard naming conventions in both the relational database and Java worlds. In addition to allowing us to specify what column each field maps to, the @Column annotation has a nullable attribute that allows us to specify if the column accepts null values or not. As we can see, the wizard automatically sets nullable to false for the entity's primary key field.

Entity Relationships

There are several annotations we can use in JPA entities to define relationships between them. In our Customer entity shown above, we can see that the wizard detected several one-to-many relationships in the CUSTOMER table, and automatically added the @OneToMany annotation to define these relationships in our entity. Notice that each field annotated with the @OneToMany annotation is of type java.util.Collection. The Customer is the "one" side of the relationship, since a customer can have many orders, many addresses (street, mail), or many telephone numbers (home, work, cell). Notice that the wizard uses generics to specify the type of objects we can add to each collection. Objects in these collections are the JPA entities mapping to the corresponding tables in our database schema.

Notice that @OneToMany annotation has a mappedBy attribute. This attribute is necessary since each of these relationships is bi-directional (we can access all addresses for a customer, and for a given address, we can obtain what customer it belongs to). The value of this attribute must match the name of the field on the other side of the relationship. Let's take a look at the Address entity to illustrate the other side of the customer-address relationship.

package com.ensode.jpa;
//imports omitted for brevity.
@Entity
@Table(name = "ADDRESS")
//Named queries omitted for brevity
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ADDRESS_ID", nullable = false)
private Integer addressId;
@Column(name = "ADDR_LINE_1")
private String addrLine1;
@Column(name = "ADDR_LINE_2")
private String addrLine2;
@Column(name = "CITY")
private String city;
@Column(name = "ZIP")
private String zip;
@JoinColumn(name = "ADDRESS_TYPE_ID", referencedColumnName = "ADDRESS_TYPE_ID")
@ManyToOne
private AddressType addressTypeId;
@JoinColumn(name = "CUSTOMER_ID", referencedColumnName = "CUSTOMER_ID")
@ManyToOne
private Customer customerId;
@JoinColumn(name = "US_STATE_ID", referencedColumnName = "US_STATE_ID")
@ManyToOne
private UsState usStateId;
// Getters, setters, constructor and other methods
// omitted for brevity.
}

Notice that the Address entity has a customerId field. This field is of type Customer, the entity we were just discussing.

A more appropriate name for this field would have been customer, the New Entity Classes from Database names the field based on the column name in the database. This is one small disadvantage of using the wizard to generate JPA entities. Of course we are free to rename the field and the corresponding getter and setter methods. Additionally, we would have to change the value of the mappedBy attribute of the @OneToMany annotation on the other side of the relationship.

Notice that the field is decorated with a @ManyToOne annotation. This annotation marks the "many" side of the one-to-many relationship between Customer and Address. Notice that the field is also decorated with the @JoinColumn annotation. The name attribute of this annotation indicates the column in the database our entity maps to that defines the foreign key constraint between the ADDRESS and CUSTOMER tables. The referencedColumnName attribute of @JoinColumn is use to indicate the primary key column of the table on the "one" side of the relationship (CUSTOMER, in our case).

In addition to one-to-many and many-to-one relationships, JPA provides annotations to denote many-to-many, and one-to-one relationships. In our schema, we have many-to-many relationships between the CUSTOMER_ORDER and ITEM tables, since an order can have many items, and an item can belong to many orders.

The table to hold orders was named CUSTOMER_ORDER since the word ORDER is a reserved word in SQL.

Let's take a look at the CustomerOrder JPA entity to see how the many-to-many relationship is defined.

package com.ensode.jpa;
//imports deleted for brevity
@Entity
@Table(name = "CUSTOMER_ORDER")
//Named queries deleted for brevity
public class CustomerOrder implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "CUSTOMER_ORDER_ID", nullable = false)
private Integer customerOrderId;
@Column(name = "ORDER_NUMBER")
private String orderNumber;
@Column(name = "ORDER_DESCRIPTION")
private String orderDescription;
@JoinTable(name = "ORDER_ITEM", joinColumns =
{@JoinColumn(name = "CUSTOMER_ORDER_ID",
referencedColumnName =
"CUSTOMER_ORDER_ID")},
inverseJoinColumns = {@JoinColumn(name = "ITEM_ID",
referencedColumnName = "ITEM_ID")})
@ManyToMany
private Collection<Item> itemIdCollection;
@JoinColumn(name = "CUSTOMER_ID", referencedColumnName = "CUSTOMER_ID")
@ManyToOne
private Customer customerId;
//Constructor, getters, setters and other methods deleted for
//brevity
}

Notice that the CustomerOrder entity has a property of type java.util.Collection named itemIdCollection.

Again, the property name generated by the wizard could be improved. A better name would have been itemCollection.

This property holds all items for the order. Notice that the field is decorated with the @ManyToMany annotation. This annotation is used to declare a many-to-many relationship between the CustomerOrder and Item JPA entities. Notice that the field is also annotated with the @JoinTable annotation. This annotation is necessary since a join table is necessary in a database schema whenever there is a many-to-many relationship between tables. Using a join table allows us to keep the data in the database normalized.

The @JoinTable annotation allows us to specify the table in the schema that is used to denote the many-to-many relationship in the schema. The value of the name attribute of @JoinTable must match the name of the join table in the schema. The value of the joinColumns attribute of @JoinColumn must be the foreign key relationship between the join table and the owning side of the relationship. We already looked at the @JoinColumn annotation when looking at one-to-many relationships. In this case, its name attribute must match the name of the column in the join table that has the foreign key relationship, and its referencedColumnName attribute must indicate the name of the primary key column on the owning side of the relationship. The value of the inverseJoinColumns attribute of @JoinTable has a similar role as its joinColumns attribute, except it indicates the corresponding columns for the non-owning side of the relationship.

The side of the many-to-many relationship containing the above annotations is said to be the owning side of the relationship, let's look at how the many-to-many relationship is defined in the non-owning side of the relationship, which, in our case is the Item JPA entity.

package com.ensode.jpa;
//Imports deleted for brevity
@Entity
@Table(name = "ITEM")
//Named queries deleted for brevity
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ITEM_ID", nullable = false)
private Integer itemId;
@Column(name = "ITEM_NUMBER")
private String itemNumber;
@Column(name = "ITEM_SHORT_DESC")
private String itemShortDesc;
@Column(name = "ITEM_LONG_DESC")
private String itemLongDesc;
@ManyToMany(mappedBy = "itemIdCollection")
private Collection<CustomerOrder> customerOrderIdCollection;
//Constructors, getters, setters and other methods
//deleted for brevity.
}

As we can see, the only thing we need to do on this side of the relationship is to create a Collection property, decorate it with the @ManyToMany annotation and specify the property name in the other side of the relationship as the value of its mappedBy attribute.

In addition to one-to-many and many-to-many relationships, it is possible to create one-to-one relationships between JPA entities.

The annotation to use to indicate a one-to-one relationship between two JPA entities is @OneToOne. Our schema doesn't have any one-to-one relationship between tables, therefore this annotation was not added to any of the entities generated by the wizard.

One-to-one relationships are not very popular in database schemas, since all data in a single entity is kept in a single table. Nevertheless JPA supports one-to-one relationships in case it is needed.

The procedure to indicate a one-to-one relationship between two entities is similar to what we have already seen, the owning side of the relationship must have a field of the type of the JPA entity at the other side of the relationship. This field must be decorated with the @OneToOne and @JoinColumn annotations.

Suppose we had a schema in which a one-to-one relationship was defined between two tables named PERSON and BELLY_BUTTON. This is a one-to-one relationship since each person has one belly button and each belly button belongs to only one person. (The reason the schema was modeled this way instead of having the columns relating to the BELLY_BUTTON table in the PERSON table escapes me, but bear with me, I'm having a hard time coming up with a good example!).

@Entity
public class Person implements Serializable {
@JoinColumn(name="BELLY_BUTTON_ID")
@OneToOne
private BellyButton bellyButton;
public BellyButton getBellyButton(){
return bellyButton;
}
public void setBellyButton(BellyButton bellyButton){
this.bellyButton = bellyButton;
}
}

If the one-to-one relationship is unidirectional (we can only get the belly button from the person), this would be all we had to do. If the relationship is bidirectional, then we need to add the @OneToOne annotation on the other side of the relationship, and use its mappedBy attribute to indicate the other side of the relationship.

@Entity
@Table(name="BELLY_BUTTON")
public class BellyButton implements Serializable(
{
@OneToOne(mappedBy="bellyButton")
private Person person;
public Person getPerson(){
return person;
}
public void getPerson(Person person){
this.person=person;
}
}

As we can see, the procedure to establish one-to-one relationships is very similar to the procedure used to establish one-to-many and many-to-many relationships.

Once we have generated JPA entities from a database, we need to write additional code containing business and presentation logic. Alternatively, we can use NetBeans to generate code for these two layers.

Generating JSF Applications from JPA Entities

One very nice feature of NetBeans is that it allows us to generate JSF applications that will perform create, read, update, and delete (CRUD) operations from existing JPA entities. This feature, combined with the ability to create JPA entities from an existing database schema, as described in the previous section, allows us to write web applications that interact with a database in record time.

To generate JSF pages from existing JPA entities, we need to right-click on the project and select New | JSF Pages from Entity Classes....

In order for us generate JSF pages from existing JPA entities, the current project must be a Web application project.

Interacting with Databases through the Java Persistence API

At this point we are presented with the New JSF Pages from Entity Classes wizard

Interacting with Databases through the Java Persistence API

We need to select one or more JPA entities. We would typically want to select all of them. They can easily be selected by clicking on the Add All>> button.

The next page in the wizard allows us to specify a package for newly created JSF managed beans. Two types of classes are generated by the wizard: JPA Controllers and JSF Classes. We can specify packages for both of these individually.

Interacting with Databases through the Java Persistence API

We are also given the opportunity to specify a folder for the JSF pages to be created. If we leave this field blank, pages will be created in our project's Web Pages folder.

The value of the JPA Controller Package and JSF Classes Package text fields default to the package where our JPA entities reside. It is a good idea to modify this default, since placing the JSF managed beans in a different package separates the data access layer classes from the user interface and controller layers of our application.

At this point in the wizard we can specify if we would like the generated pages to be Ajax enabled. This can be done by simply checking the Ajax-enable generated pages checkbox.

After clicking Finish, a complete web application that can perform CRUD operations will be created.

Interacting with Databases through the Java Persistence API

As we can see, NetBeans generates a folder for each of our entities under the Web Pages folder of our application. Each of the folders has a Detail, Edit, List, and New JSP files. The Detail JSP will display all properties for a JPA entity, the Edit JSP will allow users to update information for a specific entity, the List JSP will display all instances of a specific entity in the database, and the New JSP will provide functionality to create new entities.

The generated application is a standard JSF application; we can execute it by simply right-clicking on the project and selecting Run. At that point the usual things happen: the application server is started if it wasn't already up, the application is deployed and a web browser window is opened displaying the welcome page for our application.

Interacting with Databases through the Java Persistence API

As we can see, the welcome page contains a link corresponding to each of our JPA entities. The links will display a table displaying all existing instances of our entity in the database. Then we click on the Show All Customer Items.

Interacting with Databases through the Java Persistence API

Since we haven't inserted any data to the database yet, the page displays the message (No Customer Items Found). We can insert a customer into the database by clicking on the New Customer link.

Interacting with Databases through the Java Persistence API

Notice how an input field is generated for each property in our entity, which in turn corresponds to each column in the database table.

As we can see, an input field was generated for the primary key field of our entity. This field is only generated if the JPA entity does not use a primary key generation strategy.

For properties in which there is a one-to-many relationship, a multiple select box is generated (in our example they are empty, since we haven't added any to the database yet).

After entering some information on the page and clicking on the Create link, a new customer is inserted into the database and we are directed to the List JSP.

Interacting with Databases through the Java Persistence API

At this point we can see our newly created customer in the list of customers on this JSP. Notice that the JSP has links to Show, Edit, and Destroy (delete) the entity.

Let's say we would want to add an address for our customer. We could do so by clicking on the Index link, then clicking on Show All Address Items, then on New Address.

Interacting with Databases through the Java Persistence API

The Address entity is at the "one" end of several one-to-many relationships, notice how a combo box is generated for each one of the entities at the "many" end. Since we wish to assign this address to the customer we just added, we attempt to select a customer from the CustomerId combo box.

A better name could be used for the CustomerId field. The reason this is the label for the combo box is because it matches the property name on the Address JPA entity, which in turn could have a better name, such as customer. Recall that all entities on this project were automatically generated from an existing database schema.

Clicking on the combo box reveals a cryptic, almost undecipherable (from the users point of view anyway), label for our customer. The reason we see this label is because the labels generated for each item in the combo box come from the toString() method of the entities used to populate it. We can work around this issue by modifying the toString() method so that it returns a user-friendly String suitable to use as a label.

As we can see, the generated code from NetBeans wizards could certainly use some tweaking, such as modifying the toString() methods of each JPA entity so that it can be used as a label, modifying some of the property names on the entities so that they make more sense to us developers, modifying the labels on the generated JSF pages so that they are more user friendly. Nevertheless, as we can see we can have a fully working application completely created by a few clicks of the mouse. This functionality certainly saves us a lot of time and effort (just don't tell your boss about it).

Summary

In this article, we saw the many ways in which NetBeans can help us speed up development of applications taking advantage of the Java Persistence API (JPA).

We saw how NetBeans can generate new JPA classes with all required annotations already in place.

Additionally, we covered how NetBeans can automatically generate code to persist a JPA entity to a database table.

We also covered how NetBeans can generate JPA entities from an existing database schema, including the automated generation of JPQL named queries.

About the Author :


Suhreed Sarkar

Suhreed Sarkar is an IT consultant, trainer and technical writer. He studied Marine engineering, served on board the ship for two years, and then started journey in to IT world with MCSE in Windows NT 4.0 track. Later he studied business administration and earned MBA from University of Dhaka. He has a bunch of BrainBench certifications on various topics including PHP4, Project Management, RDBMS Concepts, E-commerce, Web Server Administration, Internet Security, Training Development, Training Delivery and Evaluation, and Technical Writing.

He taught courses on system administration, web development, e-commerce and MIS. He has consulted several national and international organizations including United Nations, and helped clients building and adopting their web portals, large scale databases and management information systems. At present he is working on building a framework for education sector MIS, and promoting use of ICTs in education.

Suhreed is renowned technical author in Bengali – having a dozen of books published on subjects covering web development, LAMP, networking, and system administration. He authored Zen Cart: E-commerce Application Development, Joomla! E-commerce with Virtuemart, and Joomla! with Flash, published by Packt Publishing.

While not busy with hacking some apps, blogging on his blog (http://www.suhreedsarkar.com), reading philosophy of Bertrand Russell or management thought of Peter F Drucker – he likes to spend some special moments with his family. Suhreed lives in Dhaka, Bangladesh

Contact Suhreed Sarkar

Books From Packt

Liferay Portal Enterprise Intranets
Liferay Portal Enterprise Intranets

ZK Developer’s Guide
ZK Developer’s Guide

EJB 3 Developer Guide
EJB 3 Developer Guide

DWR Java AJAX Applications
DWR Java AJAX Applications

Apache OFBiz Development: The Beginner's Tutorial
Apache OFBiz Development: The Beginner's Tutorial

Learning Ext JS
Learning Ext JS

Service Oriented Java Business Integration
Service Oriented Java Business Integration

Openfire Administration
Openfire Administration

 


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software