You are on page 1of 5

WEBANNOTATIONS During the lifetime of a typical web application, a number of events take place, such as HTTP requests are

created or destroyed, request or session attributes are added, removed, or modified, and so on and so forth. The Servlet API provides a number of listener interfaces we can implement in order to react to these events. All of these interfaces are in the javax.servlet package. The following table summarizes them: LISTENER INTERFACE
ServletContextListener ServletContextAttributeListener

DESCRIPTION
Contains methods for handling context initialization and destruction events. Contains methods for reacting to any attributes added, removed, or replaced in the servlet context (application scope). Contains methods for handling request initialization and destruction events. Contains methods for reacting to any attributes added, removed, or replaced in the request. Contains methods for handling HTTP session initialization and destruction events Contains methods for reacting to any attributes added, removed, or replaced in the HTTP session.

ServletRequestListener ServletRequestAttributeListener HttpSessionListener HttpSessionAttributeListener

Summary
This chapter covered how to develop, configure, package, and deploy servlets. We also covered how to process HTML form information by accessing the HTTP request object. Additionally, forwarding HTTP requests from one servlet to another was covered, as well as redirecting the HTTP response to a different server. We also discussed how to persist objects in memory across requests by attaching them to the servlet context and the HTTP session. Finally, we covered all the major new features of Servlet 3.0, including configuring web applications via annotations, pluggability through web-fragment.xml, programmatic servlet configuration, and asynchronous processing.

Database Connectivity
Any non-trivial Java EE application will persist data to a relational database. In this chapter, we will cover how to connect to a database and perform CRUD operations (Create, Read, Update, and Delete). There are two Java EE APIs that can be used to interact with a relational

database: the Java Database Connectivity (JDBC) API and the Java Persistence API (JPA). Both these APIs will be discussed in this chapter. Some of the topics covered in this chapter include: Retrieving data from a database through JDBC Inserting data into a database through JDBC Updating data in a database through JDBC Deleting data in a database through JDBC Retrieving data from a database through JPA Inserting data into a database through JPA Updating The Java Database Connectivity (JDBC) API is the standard API used for Java applications to interact with a database. Although JDBC is not part of the Java EE specification, it is used very frequently in Java EE applications. data in a database through JPA Deleting data in a database through JPA Building queries programmatically through the JPA 2.0 Criteria API Automating data validation through JPA 2.0's Bean Validation support

JDBC
JDBC allows us to send queries to a database to perform select, insert, update, and delete operations. The most common way of interacting with a database through JDBC is through the java.sql.PreparedStatement interface. Using prepared statements through this interface offers a number of benefits over using standard JDBC statement objects. Some of the benefits of prepared statements include: Prepared statements are compiled into the RDBMS the first time they are executed, therefore increasing performance Prepared statements are immune to SQL injection attacks Prepared statements free us from explicitly adding single quotes (') to our SQL statements to handle character values The java.sql.PreparedStatement interface has two methods that are very frequently used to send queries to the database: executeQuery() and executeUpdate(). The executeQuery() method is used to issue select statements to the database and returns an instance of java.sql.ResultSet containing the rows returned from the query. The executeUpdate() method is used to issue insert, update, and delete statements to the database. It returns an int value corresponding to the number of rows affected by the query. In the following sections, we illustrate database interaction through these two methods.

The Java Persistence API


The Java Persistence API (JPA) was introduced to Java EE in version 5 of the specification. Like its name implies, it is used to persist data to a Relational Database Management System. JPA replaced entity beans in Java EE 5 (of course, for backwards compatibility, entity beans are still supported). Java EE Entities are regular Java classes. The Java EE container knows these classes are entities because they are decorated with the @Entity annotation.

Entity relationships
In the previous section, we saw how to retrieve, insert, update, and delete single entities from the database. Entities are rarely isolated; in the vast majority of cases, they are related to other entities. Entities can have one-to-one, one-to-many, many-to-one, and many-to-many relationships. For example, in the CustomerDB database, there is a one-to-one relationship between the LOGIN_INFO and CUSTOMERS tables. This means that each customer has exactly one corresponding row in the LOGIN_INFO table. There is also a one-to-many relationship between the CUSTOMERS table and the ORDERS table. This is because a customer can place many orders. Additionally, there is a many-to-many relationship between the ORDERS table and the ITEMS table. This is because an order can contain many items and an item can be found in many orders. In the next few sections, we discuss how to establish relationships between JPA entities.

One-to-one relationships
One-to-one relationships occur when an instance of an entity can have zero or one corresponding instance of another entity. One-to-one entity relationships can be bidirectional (each entity is aware of the relationship) or unidirectional (only one of the entities is aware of the relationship). In the CUSTOMERDB database, one-to-one mapping between the LOGIN_INFO and CUSTOMERS tables is unidirectional, as the LOGIN_INFO table has a foreign key to the CUSTOMERS table, but not the other way around. As we will soon see, this fact does not stop us from creating a bidirectional one-to-one relationship between the Customer entity and the LoginInfo entity.

One-to-many relationships
With JPA, one-to-many entity relationships can be bidirectional (one entity contains a many-toone relationship and the corresponding entity contains an inverse one-to-many relationship). With SQL, one-to-many relationships are defined by foreign keys in one of the tables. The "many" part of the relationship is the one containing a foreign key to the "one" part of the relationship. One-to-many relationships defined in an RDBMS are typically unidirectional, as making them bidirectional usually results in denormalized data. Just like when defining a unidirectional one-to-many relationship in an RDBMS, in JPA the "many" part of the relationship is the one that has a reference to the "one" part of the relationship. Therefore, the annotation used to decorate the appropriate setter method is @ManyToOne.

Many-to-many relationships
In the CUSTOMERDB database, there is a many-to-many relationship between the ORDERS table and the ITEMS table. We can map this relationship by adding a new Collection<Item> field to the Order entity and decorating it with the @ManyToMany annotation.

Composite primary keys


Most tables in the CUSTOMERDB database have a column with the sole purpose of serving as a primary key (this type of primary key is sometimes referred to as a surrogate primary key or as an artificial primary key). However, some databases are not designed this way. Instead, a column in the database that is known to be unique across rows is used as the primary key. If there is no column whose value is not guaranteed to be unique across rows, then a combination of two or more columns is used as the table's primary key. It is possible to map this kind of primary key to JPA entities by using a primary key class. There is one table in the CUSTOMERDB database that does not have a surrogate primary keythe ORDER_ITEMS table. This table serves as a join table between the ORDERS and the ITEMS tables. In addition to having foreign keys for these two tables, this table has an additional column called ITEM_QTY, which stores the quantity of each item in an order. As this table does not have a surrogate primary key, the JPA entity mapping to it must have a custom primary key class. In this table, the combination of the ORDER_ID and ITEM_ID columns must be unique.

Java Persistence Query Language


All of our examples that obtain entities from the database so far have conveniently assumed that the primary key for the entity is known ahead of time. We all know that frequently this is not the case. Whenever we need to search for an entity by a field other than the entity's primary key, we must use the Java Persistence Query Language (JPQL). JPQL is an SQL-like language used for retrieving, updating, and deleting entities in a database.

New features introduced in JPA 2.0


Version 2.0 of the JPA specification introduces some new features to make working with JPA even easier. In the following sections, we discuss some of these new features:

Criteria API
One of the main additions to JPA in the 2.0 specification is the introduction of the Criteria API. The Criteria API is meant as a complement to the Java Persistence Query Language (JPQL). Although JPQL is very flexible, it has some problems that make working with it more difficult than necessary. For starters, JPQL queries are stored as strings and the compiler has no way of validating JPQL syntax. Additionally, JPQL is not type safe. We could write a JPQL query in which our where clause could have a string value for a numeric property and our code would compile and deploy just fine. To get around the JPQL limitations described in the previous paragraph, the Criteria API was introduced to JPA in version 2.0 of the specification. The Criteria API allows us to write JPA queries programmatically, without having to rely on JPQL.

Bean Validation support

Another new feature introduced in JPA 2.0 is support for JSR 303, Bean Validation. Bean Validation support allows us to annotate our JPA entities with Bean Validation annotations. These annotations allow us to easily validate user input and perform data sanitation.

Summary
This chapter covered how to access data in a database via both the Java Database Connectivity (JDBC) and through the Java Persistence API (JPA). We covered how to obtain data from the database by using JDBC via the executeQuery() method defined in the java.sql.PreparedStatement interface. We also covered how to insert, update, and delete data in the database via the executeUpdate() method defined in the same interface. Additionally, using dependency injection to inject a DataSource into an object was also covered. Setting a Java class as an entity by decorating it with the @Entity annotation was also covered. Additionally, we covered how to map an entity to a database table via the @Table annotation. We also covered how to map entity fields to database columns via the @Column annotation, as well as declaring an entity's primary key via the @Id annotation. Using the javax.persistence.EntityManager interface to find, persist, and update JPA entities was also covered. Defining both unidirectional and bidirectional one-to-one, one-to-many, and many-to-many relationships between JPA entities was covered as well. Additionally, we covered how to use JPA composite primary keys by developing custom primary key classes. We also covered how to retrieve entities from a database by using the Java Persistence Query Language (JPQL). We then discussed some new JPA 2.0 features such as the Criteria API that allows us to build JPA queries programmatically, the Metamodel API that allows us to take advantage of Java's type safety when working with JPA, and Bean Validation that allows us to easily validate input by simply annotating our JPA entity fields

You might also like