Jump to: navigation, search

EclipseLink/Examples/JPA/JSF Tutorial

Catnicon.gifThis page is under construction.



Tutorial: Build a Web Application (JSF) Using JPA

This tutorial will walk you through the basic steps of developing, packaging, and deploying a Web application using the EclipseLink.

In this application, a Java Server Faces (JSF) presentation layer will make use of JPA for persistence outside of an EJB 3.0 container.

This figure shows the object model that this tutorial uses.

Tutorial Object Model

Tutorial Object Model


Required Software

This tutorial uses:

  • JDK 1.6
  • Eclipse 3.3
  • Web container. This tutorial assumes that you are using Apache Tomcat.
  • Relational database. This tutorial assumes that you are using Apache Derby.
  • EclipseLink

Source Code:

  • Example Source Code - this is a completed version of the tutorial that you can build and deploy immediately.
  • Tutorial Source Code - this is the starting point for the tutorial. By the end of the tutorial, you will make this code match the example source code.


Setup and Configuration

Before starting this tutorial, you must setup and configure the required software:

  1. Install JDK 5.0
  2. Install Ant
  3. Install the example and tutorial source files:
    • Create a directory in which to unzip the example source files.This is the <EXAMPLE_HOME> directory.
    • Unzip the order-jsf-jpa-example.zip file to the <EXAMPLE_HOME> directory.This directory contains the completed tutorial source.
    • Create a directory in which to unzip the tutorial source files.This is the <TUTORIAL_HOME> directory.
    • Unzip the order-jsf-jpa-tutorial.zip file to the <TUTORIAL_HOME> directory.This directory contains the stubbed tutorial source that you will complete in this tutorial.

    For more information about the structure and content of the <EXAMPLE_HOME> and <TUTORIAL_HOME> directories, see Understanding the Tutorial Source Files.
  4. Install and setup your relational database:
    • Apache Derby
    • Add your relational database JDBC driver to:
      • <EXAMPLE_HOME>\lib
      • <TUTORIAL_HOME>\lib
  5. Install and setup your Web container:
  6. Install EclipseLink:
    • Add eclipselink.jar and persistence.jar to:
      • <EXAMPLE_HOME>\lib
      • <TUTORIAL_HOME>\lib
  7. Validate your installation:
    • Edit the <EXAMPLE_HOME>\persistence-unit\src\META-INF\persistence.xml file and set the following properties to match your relational database:
    <property name="eclipselinkjdbc.driver" value="<jdbc-driver>"/>
    <property name="eclipselink.jdbc.url" value="<jdbc-url>"/>
    <property name="eclipselink.jdbc.password" value="<jdbc-password>"/>
    <property name="eclipselink.jdbc.user" value="<jdbc-user>"/>
    


    Where:

    • <jdbc-driver> is the name of your JDBC driver class. Example: org.apache.derby.jdbc.ClientDriver.
    • <jdbc-url> is the JDBC connection URL to your database. Example: jdbc:derby://localhost:1527/sample;create=true.
    • <jdbc-password> is the JDBC password you use to connect to your database. Example: demo.
    • <jdbc-user> is the JDBC user name you use to connect to your databse. Example: demo
  8. Create and populate the database.
    • From the command line, change directories to the <EXAMPLE_HOME> directory and execute:
    ant -f build.xml generate-tables
    ant -f build.xml populate-data
    
    • Confirm that TABLE CREATE statements are visible in the log messages written to standard out.
    If they are, then you are connecting to the database successfully.
    If they are not, then you are not connecting to the database. In this case, confirm your persistence.xml file settings and ensure that your database is up and running.
  9. Deploy the web application.
    • From the command line, change directories to the <EXAMPLE_HOME> directory and execute:
    ant -f build.xml package.webapp
    
    • Deploy the <EXAMPLE_HOME>\web-application\deploy\jpa-example.war file. See Deploying to Tomcat
  10. Run the application. See: Running the Application on Tomcat

Confirm that you can see the tutorial application main page as this figure shows.You are now ready to start the tutorial (see #Tutorial Steps).

Tutorial Application Main Page

Tutorial Application Main Page


Understanding the Tutorial Source Files

After unzipping the order-jsf-jpa-example.zip and order-jsf-jpa-tutorial.zip (see Setup and Configuration), you have an <EXAMPLE_HOME> and <TUTORIAL_HOME> directory.

These directories contain the same structure as Structure of <EXAMPLE_HOME> and <TUTORIAL_HOME> shows. Important Subdirectories in <EXAMPLE_HOME> and <TUTORIAL_HOME> describes the important content of these subdirectories.

The source files in the <EXAMPLE_HOME> are completed versions of the tutorial that you can build and deploy immediately.

The source files in the <TUTORIAL_HOME> subdirectory are the starting point for the tutorial. By the end of the tutorial, you will make this code match the example source code.


Structure of <EXAMPLE_HOME> and <TUTORIAL_HOME>

build.xml
extras/
    bin/
    classes/
    src/org/eclipse/persistence/jpa/example/inventory/tools/
        DDLGenerator.java
        Populator.java
lib/
    - JSF and JSTL JARs
    - JDBC driver JARs (user-supplied)
    - EclipseLink JPA JARs (user-supplied)
persistence-unit/
    classes/
    deploy/
    src/META-INF
        persistence.xml
    src/org/eclipse/persistence/jpa/example/inventory/
        model/
            Inventory.java
            Item.java
            Order.java
        nonentity/
            Category.java
web-application/
    classes/
    deploy/
    public_html/
        *.jsp
        css/
        images/
        WEB-INF/
            faces-config.xml
            web.xml
    src/org/eclipse/persistence/jpa/example/inventory/
        services/
            InventoryService.java
            OrderService.java
        services/impl/
            JPAResourceBean.java
            ManagedInventoryBean.java
            ManagedOrderBean.java
        ui/
            InventoryManagerBean.java


Important Subdirectories in <EXAMPLE_HOME> and <TUTORIAL_HOME>

Subdirectory Description

extras/

Contains source files that are not directly executed by the tutorial application.

classes/

The directory in which the extra/src source files are compiled by the tutorial build.xml Ant script.

src/

The src/org/eclipse/persistence/jpa/example/inventory/tools/ directory contains helper classes that you can optionally invoke with tutorial build.xml Ant script targets:

  • generate-tables - invokes DDLGenerator to generate the tutorial application's database tables.
  • populate-data - invokes Populator to populate the tutorial application's database tables.

lib/

The lib directory contains all the JAR files that the tutorial application depends on. In particular, this includes:

  • JSF and JSTL JARs (included)
  • JDBC driver JARs (user-supplied)
  • EclipseLink JAR files (user-supplied)

persistence-unit/

Contains the source files for persistent JPA entities.

classes/

This is a temporary directory where the persistence unit source files are built before packaging into the persistence unit archive.

deploy/

This directory will contain the built and packaged persistence unit persistence-unit.jar file.

src/

This directory contains the sources required for the persistence unit including the domain classes.It also contains the persistence.xml file located in the sub-directory META-INF, as per the JPA specification.

web-application/

Contains the source files that implement the services and user interface of the tutorial application that use the JPA entities.

classes/

This is a temporary directory where the sources are built before packaging into the deployable archive.

deploy/

This directory will contain the built deployable Web application, jpa-example.war. This is built using the ant target package.webapp.

public_html/

Contains the presentation layer of the application including JSPs, stylesheets (css/), images (images/), and deployment descriptor (WEB-INF/web.xml).

src/

This directory includes the sources for the controller layer of the application.

  • The org/eclipse/persistence/jpa/example/inventory/services directory contains the sources for the services interfaces that provide access to the persistence layer:
  • The org/eclipse/persistence/jpa/example/inventory/services/impl directory contains the classes that implement the service interfaces.The ManagedOrderBean implements the OrderService interface.The ManagedInventoryBean implements the InventoryService interface.The JPAResourceBean is a helper class that the tutorial application uses to acquire an EntityManager for the tutorial application's persistence unit.
  • The org/eclipse/persistence/jpa/example/inventory/ui directory contains the InventoryManagerBean class that drives the tutorial application user interface.



Tutorial Steps

The following procedure leads you through the important steps in creating the tutorial application. At each step, you will be directed to modify the <TUTORIAL_HOME> source files as necessary.


Creating an Eclipse Project

  1. Select File > New > Project. The New Project dialog appears.
  2. Select Java Project and click Next. The New Java Project wizard appears.
  3. On the Create a Java Project dialog, complete the following fields and click Next.
    • For the Project Name, enter EclipseLink Tutorial.
    • In the Contents area, select Create project from existing source and click Browse. Select the <TUTORIAL_HOME> directory.
  4. On the Java Settings dialog, select the Libraries.
  5. On the Libraries tab, click Add External JARs and select the eclipselink.jar and persistence.jar.
  6. Click Finish. Eclipse creates the project and opens the Java perspective.


Annotating the Entities

Annotations are a simple, expressive means of decorating Java source code with metadata that is compiled into the corresponding Java class files for interpretation at runtime by a JPA persistence provider to manage JPA behavior.

Persistent classes are decorated with JPA annotations to tell the JPA persistence provider what classes require persistence and to specify persistent class details.

In most cases, you can rely on JPA defaults. This tutorial shows the required annotations and some common optional annotations.

For more information, see Using EclipseLink JPA Extensions (ELUG).

This section describes:


Annotating the Inventory Entity

This section describes how to annotate the Inventory.java file. This is a plain old Java object (POJO). It is one of the persistent entities we want to manage using EclipseLink JPA.

  1. In Eclipse, open the <TUTORIAL_HOME>\persistence-unit\src\org\eclipse\persistence\jpa\example\inventory\model\Inventory.java source file.
  2. Designate this class as a persistent entity using the @Entity annotation as this example shows.
    @Entity in Inventory.java
    @Entity
    public class Inventory {
        ...
    }
    


    By default, the name of an entity is its class name.Also by default, the entity name is the name of the entity's database table. You can use the @Table annotation to override this default behavior (for an example, see Annotating the Order Entity).

    An entity's table will contain all its persistent fields. JPA specifies that all the fields of an entity are persistent unless they are decorated with the @Transient annotation.
  3. Designate a persistent field as the entity's primary key using the @Id annotation as this example shows.
    @Id in Inventory.java
    @Entity
    public class Inventory {
        @Id
        protected long id;
        ...
        public void setItem(Item item) {
            this.item = item;
            this.id = item.getSKU();
        }
        ...
    }
    

    Each entity must have a primary key.The Inventory class field id is designated as the primary key. In this case, a @GeneratedValue annotation is not used because the Inventory entity gets its primary key value from its Item as the Inventory method setItem shows.
  4. Specify the characteristics of the database table column that corresponds to the primary key field using the @Column annotation as this example shows.
    @Column in Inventory.java
    @Entity
    public class Inventory {
        @Id
        @Column(name="ITEM_SKU", insertable=false, updatable=false)
        protected long id;
        ...
        public void setItem(Item item) {
            this.item = item;
            this.id = item.getSKU();
        }
        ...
    }
    

    By default, JPA specifies that for each entity, each persistent field will correspond to a column in the entity's relational database table where the column name and type correspond to the field name and type.You can use the @Column annotation to override this default behavior.In the Inventory class, the @Column annotation is used to fine-tune the relational database column for field id as @Column in Inventory.java shows. Because the Inventory entity gets its primary key value from its Item as the Inventory method setItem shows, we must ensure that this value is never overwritten in the database. In this case, we use the @Column annotation to configure the column as not insertable or updatable. This means the JPA persistence provider will not include this column in SQL INSERT or SQL UPDATE statements. Because this column contains the foreign key to the Inventory class's Item, we use the @Column annotation attribute name to specify a name for this column that we can use when we specify the join column for the OneToOne mapping we will make to Item (see step 5 and 6).
  5. Specify the relationship between the Inventory entity and the Item entity using the @OneToOne annotation as this example shows.
    @OneToOne in Inventory.java
    @Entity
    public class Inventory {
        @Id
        @Column(name="ITEM_SKU", insertable=false, updatable=false)
        protected long id;
    
        @OneToOne
        protected Item item;
        ...
        public void setItem(Item item) {
            this.item = item;
            this.id = item.getSKU();
        }
    }
    


    By default, a JPA persistence provider will automatically manage basic mappings (for most Java primitive types, wrappers of the primitive types, and enums). You can use the @Basic annotation to fine-tune basic mappings.You must specify mappings for relationships. In addition to the @OneToOne annotation, you can use the following annotations for relationship mappings:

    The Inventory class field item is decorated with the @OneToOne annotation to specify the relationship between Inventory and Item as @OneToOne in Inventory.java shows.
  6. Specify that the foreign key column that references the Item is the Inventory column named ITEM_SKU using the @JoinColumn annotation as this example shows.
    @JoinColumn in Inventory.java
    @Entity
    public class Inventory {
        @Id
        @Column(name="ITEM_SKU", insertable=false, updatable=false)
        protected long id;
    
        @OneToOne
        @JoinColumn(name="ITEM_SKU")
        protected Item item;
        ...
        public void setItem(Item item) {
            this.item = item;
            this.id = item.getSKU();
        }
    }
    
  7. Specify a persistent field as the optimistic locking field using the @Version annotation as this example shows.
    @Version in Inventory.java
    @Entity
    public class Inventory {
        @Id
        @Column(name="ITEM_SKU", insertable=false, updatable=false)
        protected long id;
    
        @OneToOne
        @JoinColumn(name="ITEM_SKU")
        protected Item item;
        ...
        @Version
        protected int version;
        ...
        public void setItem(Item item) {
            this.item = item;
            this.id = item.getSKU();
        }
    }
    

    The Inventory class field version is decorated with the @Version annotation to specify it as the optimistic locking field.By default, a JPA persistence provider assumes that the application is responsible for data consistency. We recommend that you use the @Version annotation to enable JPA persistence provider-managed optimistic locking by specifying the version field or property of an entity class that serves as its optimistic lock value.
  8. Define a named query using the @NamedQuery annotation as this example shows.
    @NamedQuery in Inventory.java
    @Entity
    
    @NamedQuery(
        name="inventoryForCategory",
        query="SELECT i FROM Inventory i WHERE i.item.category = :category and i.quantity <= :maxQuantity"
    )
    public class Inventory {
        ....
    }
    

    In a JPA application, you can use an EntityManager to create JPA query language queries dynamically at runtime or you can pre-define such queries using the @NamedQuery annotation and execute them by name at runtime (see Using JPA Queries). This is convenient for frequently used or complex queries.If you want to define two or more named queries, you must use the @NamedQueries annotations as is done in Order.java (see @NamedQueries in Order.java).You can also create native SQL queries (see @NamedNativeQuery and the @NamedNativeQueries).
  9. Save and close the file.


Annotating the Item Entity

This section describes how to annotate the Item.java file. This is a plain old Java object (POJO). It is one of the persistent entities we want to manage using JPA.


  1. In Eclipse, open the <TUTORIAL_HOME>\persistence-unit\src\org\eclipse\persistence\jpa\example\inventory\model\Item.java source file.
  2. Designate this class as a persistent entity using the @Entity annotation as this example shows.
    @Entity in Item.java
    @Entity
    public class Item {
        ...
    }
    
  3. Designate a persistent field as the entity's primary key using the @Id annotation as this example shows.
    @Id in Item.java
    @Entity
    public class Item {
        protected long SKU;
        ...
        @Id
        @GeneratedValue
        public long getSKU() {
            return SKU;
        }
        ...
    }
    


    The Item class property getSKU is designated as the primary key as @Id in Item.java shows. In general, you can annotate either the field (as in Inventory.java) or the property associated with a field. The @GeneratedValue annotation tells the JPA persistence provider to take responsibility for sequencing: generating and managing unique identifier values for this field.

  4. Specify a persistent field as the optimistic locking field using the @Version annotation as this example shows.
    @Version in Item.java
    @Entity
    public class Item {
        protected long SKU;
        ...
        @Id
        @GeneratedValue
        public long getSKU() {
            return SKU;
        }
        ...
        @Version
        public void setVersion(int version) {
            this.version = version;
        }
        ...
    }
    


    The Item class property setVersion is decorated with the @Version annotation to specify that corresponding field version is the optimistic locking field.
  5. Save and close the file.