Java EE Development with Eclipse

5 (1 reviews total)
By Deepak Vohra
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. EJB 3.0 Database Persistence

About this book

Java EE is the industry standard on enterprise computing and Oracle WebLogic Server is the most comprehensive platform for enterprise applications. The book combines Java EE with WebLogic Server in the most commonly used Java IDE, the Eclipse IDE 3.7.

"Java EE Development with Eclipse" is the only book on Eclipse IDE for Java EE Developers. The book is a practical guide for using the most commonly used Java EE technologies and frameworks in Eclipse IDE. Sample applications are available in downloadable format and may be customized to meet requirements. Oracle Enterprise Pack for Eclipse 12c, an enhancement to Eclipse IDE, providing additional project facets and an integrated support for Oracle WebLogic Server is used.

"Java EE Development with Eclipse" is based on developing applications with some of the commonly used technologies using the project facets in Eclipse 3.7 and its enhancement Oracle Enterprise Pack for Eclipse 12c.

The book starts with a discussion on EJB 3.0 database persistence with Oracle database XE and Oracle WebLogic Server. JAXB is discussed in the context of bi-directional mapping between XML and Java. A generic web project is developed for PDF and Excel spread sheet reports. JavaServer Faces, the most commonly used view component in web applications is discussed for developing a data table. Facelets, which was integrated into JSF with 2.0 version is discussed in the context of templating. ADF Faces components are used to develop another user interface (UI) application. Web services are discussed with JAX-WS and JAX-RS technologies. Java EE frameworks Ajax and Spring are also discussed.

Publication date:
December 2012
Publisher
Packt
Pages
426
ISBN
9781782160960

 

Chapter 1. EJB 3.0 Database Persistence

EJB's entity beans are the most common technology for database persistence. Developing entity EJBs requires a Java IDE, an application server, and a relational database. Eclipse 3.7 provides wizards for developing entity beans and session facades. In this chapter, we shall develop EJB 3.0 entity beans including session facades. We shall deploy the EJB application to WebLogic Server 12c (12.1.1) and test database persistence with the Oracle database 11g XE. In this chapter, we shall learn the following:

  • Configuring a data source in WebLogic Server (WLS) with the Oracle database

  • Creating tables in the Oracle database

  • Creating an Enterprise JavaBeans (EJB) project

  • Adding the Java Persistence API (JPA) project facet

  • Generating entity beans from database tables

  • Creating a session bean facade

  • Creating the application.xml file

  • Creating a test client

  • Packaging and deploying the entity bean application

  • Testing the JavaServer Pages (JSP) client

 

Configuring a data source


In this section we shall configure a data source in Oracle WebLogic Server 12c. First, download and install the Oracle WebLogic Server from http://www.oracle.com/technetwork/middleware/ias/downloads/wls-main-0971. Configure the base_domain structure in the WebLogic Server console. We need to create a data source so that when we deploy and run the application in the server, the application has access to the database. Log in to the WebLogic Server Administration Console server for the base_domain domain using the URL http://localhost:7001/Console. In the base_domain domain structure, expand the Services tab and select the Data Sources node. In the Data Sources table, click on New and select Generic Data Source as shown in the following screenshot:

In Create a New JDBC Data Source, specify a data source name and JNDI Name (for example, jdbc/OracleDS) for the data source. The database shall be accessed using JNDI Name lookup in the Creating a session bean facade section. Select Database Type as Oracle and click on Next as shown in the following screenshot:

In JDBC Data Source Properties, select Database Driver as Oracle's Driver (Thin XA). Another JDBC driver may also be selected based on requirements. Refer to the Selection of the JDBC Driver document available at http://docs.oracle.com/cd/E14072_01/java.112/e10590/keyprog.htm#i1005587 for selecting a suitable JDBC driver. Click on Next as shown in the following screenshot:

By default, an XA JDBC driver supports global transactions and uses the Two-Phase Commit global transaction protocol. Global transactions are recommended for EJBs using container managed transactions for relation between the JDBC driver (XA or non-XA) transactionality and EJB container managed transactions. Click on Next as shown in the following screenshot. (for more information on global transactions, refer http://docs.oracle.com/cd/E23943_01/web.1111/e13737/transactions.htm):

Specify Database Name as XE, Host Name as localhost, Port as 1521, Database User Name and Password as OE, and click on Next as shown in the following screenshot:

The Driver Class Name textbox and connection URL textbox get configured. Click on the Test Configuration button to test the database connection. If a connection gets established the message Connection test succeeded. gets displayed. Click on Next as shown in the following screenshot:

In Select targets, select the AdminServer option and click on Finish. A data source gets added to the data sources table. The data source configuration may be modified by clicking on the data source link as shown in the following screenshot:

 

Creating tables in the Oracle database


We need to create database tables for database persistence. Create database tables CATALOG, EDITION, SECTION, and ARTICLE with the following SQL script; the script can be run from the SQL command line:

CREATE TABLE CATALOG (id INTEGER PRIMARY KEY NOT NULL, 
journal VARCHAR(100));
CREATE TABLE EDITION (id INTEGER PRIMARY KEY NOT NULL, 
edition VARCHAR(100));
CREATE TABLE SECTION (id VARCHAR(100) PRIMARY KEY NOT NULL, 
sectionName VARCHAR(100));
CREATE TABLE ARTICLE(id INTEGER PRIMARY KEY NOT NULL, 
title VARCHAR(100));

As Oracle database does not support the autoincrement of primary keys, we need to create sequences for autoincrementing, one for each table. Create sequences CATALOG_SEQ, EDITION_SEQ, SECTION_SEQ, and ARTICLE_SEQ with the following SQL script.

CREATE SEQUENCE CATALOG_SEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 NOCACHE; 
CREATE SEQUENCE EDITION_SEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 NOCACHE; 
CREATE SEQUENCE SECTION_SEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 NOCACHE; 
CREATE SEQUENCE ARTICLE_SEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 NOCACHE;

We also need to create join tables between tables. Create join tables using the following SQL script:

CREATE TABLE  CATALOGEDITIONS(catalogId INTEGER, editionId INTEGER);
CREATE TABLE EditionCatalog(editionId INTEGER, catalogId INTEGER);
CREATE TABLE EditionSections (editionId INTEGER, sectionId INTEGER);
CREATE TABLE SectionEdition (sectionId INTEGER, editionId INTEGER);
CREATE TABLE SectionArticles(sectionId INTEGER, articleId INTEGER);
CREATE TABLE ArticleSection(articleId INTEGER, sectionId INTEGER);
 

Creating an EJB project


Now, we shall create an EJB project to create entity beans.

In Eclipse, go to File | New | Other to create an EJB project. In the New wizard, select EJB Project from the EJB folder and click on Next as shown in the following screenshot:

Specify a Project name and click on New Runtime to configure a target runtime for Oracle WebLogic Server 12c if not already configured, as shown in the following screenshot:

In New Server Runtime Environment, select the Oracle WebLogic Server 12c (12.1.1) server, tick Create a new local server checkbox, and then click on Next as shown in the following screenshot:

Select the WebLogic home directory, and the Java home directory also gets specified. Click on Next as shown in the following screenshot:

Select Server Type as Local and then select Domain Directory as C:\Oracle\Middleware\user_project\domains\base_domain. Click on Finish as shown in the screenshot:

The Target runtime server gets configured. Select EJB module version as 3.1. Select the default Configuration and click on Next as shown in the following screenshot:

Select the default Java configuration for Source folders on build path as ejbModule and Default output folder as build/classes, and click on Next as shown in the following screenshot:

Select the default EJB module configuration and click on Finish. An EJB project gets created. The EJB project does not contain any EJBs, which we shall add in subsequent sections.

Right-click on the project node in the Project Explorer tab and select Project Properties. Select Project Facets in the Properties window. The EJB project should have the EJB Module project facet enabled as shown in the following screenshot:

Session beans require an EJB project and entity beans require the JPA project facet for database persistence. We have created an EJB project but this EJB project does not have the JPA project facet enabled by default. In the next section, we shall add the JPA facet to the EJB project.

 

Adding the JPA facet


We require the JPA project facet to create entity beans. We could have created a JPA project to start with, but to create a session bean facade we first created an EJB project; session beans require an EJB project by default. To add the JPA project facet, right-click on the project in Project Explorer and select Properties. Select the Project Facets node and select the JPA 1.0 project facet. Click on the Further configuration available link as shown in the screenshot:

In JPA Facet, select Platform as Generic 1.0. Select JPA implementation as Oracle TopLink 11g R1. We also need a database connection for JPA. To configure a new Connection, click on the Add connection link as shown in the following screenshot:

In Connection Profile, select the Oracle Database Connection profile, specify a connection Name and click on Next as shown in the following screenshot:

In the Specify a Driver and Connection Details window, select the driver as Oracle Database 10g Driver. Specify SID as XE, Host as localhost, Port number as 1521, User name as OE, and Password as OE. The Connection URL gets specified. Now, click on Test Connection as shown in the following screenshot:

A Ping succeeded message indicates that the connection got established. Click on Next and then click on Finish in Summary. A Connection for the JPA Facet gets configured. Click on OK as shown in the following screenshot:

The connection profile we have configured is for the JPA project facet, not to run client applications to entity beans. The data source we configured in the WebLogic server with JNDI jdbc/OracleDS is for running client applications to entity beans. Click on Apply in Properties to install the JPA facet as shown in the following screenshot:

A node for JPA Content gets added to the EJB project. A persistence.xml configuration file gets added.

 

Creating entity beans from tables


In this section, we shall create entities from database tables we created earlier. Select the project node in Project Explorer and go to File | New | Other. In the New wizard window, select JPA Entites from Tables from the JPA folder as shown in the following screenshot. Click on Next. Alternatively, you can right-click on the project node in Project Explorer and select Generate Entities from Tables from JPA Tools.

In Select Tables, select the database connection configured when adding the JPA project facet. Select the OE Schema. Select the CATALOG, EDITION, SECTION, and ARTICLE tables. Select the checkbox Update class list in persistence.xml and click on Next as shown in the following screenshot:

Defining entity relationships

The entities to be generated have relationships between them. The Catalog entity has a one-to-many relationship with the Edition entity. The Edition entity has a one-to-many relationship with the Section entity and the Section entity has a further one-to-many relationship with the Article entity. In Table Associations, we shall define the associations between the tables. Click on the + button to create an association as shown in the following screenshot:

In Association Tables, select the tables to create an association between them. We will need to create an association for each of the relationships. Click on the button for the Table 1 field as shown in the following screenshot:

Select the CATALOG table and click on OK, as shown in the following screenshot:

Similarly, select EDITION as Table 2. The Association kind is Simple association by default, which is what we need. Now, click on Next as shown in the following screenshot:

Specify the join columns between the CATALOG and EDITION tables as ID using the Add button and click on Next as shown in the following screenshot:

As the Catalog entity has a one-to-many relation with the Edition entity, in Association Cardinality select One to many and click on Finish as shown in the following screenshot:

The table association between the CATALOG and EDITION tables gets defined and the table join also gets defined.

Setting cascade

We need to set the cascade value for the association. Cascading is used to cascade database table operations to related tables. Select the button adjacent to the Cascade field for the catalog property as shown in the following screenshot:

Cascade specifies the operations that must be cascaded to the target of the association. The join table is defined on the owning side of the association and cascade operations may be initiated from the owning side. In a one-to-many relationship, the many side is always the owning side of the relationship, which makes the Edition the owning side. But, in a bi-directional relationship operations may be initiated from the non-owning side by specifying a join table on the non-owning side also. The mappedBy element is only specified on the non-owning side. In the Edition entity, select the Cascade operations to be persist, merge, and refresh. The remove option is not included as we don't want to delete the one-side entity if a many-side entity is deleted as other many-side entities may still be present. Click on OK as shown in the following screenshot:

Similarly, select the Cascade button for the Catalog entity as shown in the following screenshot:

Set the Cascade element to all as we want to delete all Edition entities if the associated Catalog entity is deleted as shown in the following screenshot:

The Cascade values get specified. Similarly, define associations between the EDITION and SECTION, and SECTION and ARTICLE tables. After the associations are defined, click on Next as shown in the following screenshot:

Generating default entities

In this section, we shall customize the default entity generation. The aspects of entities that may be customized are the Table Mapping (primary key generator, sequence name, entity access, association fetch, and collection properties type) and Java class. EclipseLink creates entity identifiers (primary keys) using one of the strategies specified in the JPA specification; sequence objects, identity columns, tables, or provider specified strategy. Oracle database supports sequences, therefore we shall use sequence as the Key generator. Specify a sequence generator with Sequence name to be the pattern $table_seq. The $table variable shall be replaced by the table name. Specify Entity access as Property, and Associations fetch as Eager. With Eager fetching the associated entities are immediately fetched when an entity is retrieved. Select Collection properties type as java.util.List. Specify the Source Folder path and Package for the entities and click on Next.

The provision to customize individual entities is provided, but we don't need to customize individual entities as we already customized the default entity generation which applies to all the entities. Now, click on Finish as shown in the following screenshot:

The entities Catalog, Edition, Section, and Article get created as shown in the following screenshot:

A JPA diagram that shows the relationships between the different entities may also be created. Right-click on perstistence.xml and select Open Diagram as shown in the following screenshot:

Click on each of the entities in the Project Explorer tab and drag the entities to the JPA Diagram tab. The relationships diagram between the entities gets displayed as shown in the following screenshot:

The entities are generated automatically by the JPA project facet and may need some customization, such as adding named queries. Next, we construct the entities, and add additional configuration for the entity relationships. We shall discuss the subsequent sections including the entity code automatically generated. If some of the subsequent additions are already in the entities, those code additions do not have to be re-added.

Creating the Catalog entity

The Catalog entity is the persistent class for the CATALOG database table. The class is annotated with the @Entity annotation that specifies the class to be an entity bean named queries findCatalogAll, which selects all Catalog entities, and findCatalogByJournal, which selects a Catalog entity by Journal, are specified using the @NamedQueries and @NamedQuery annotations.

@Entity
@NamedQueries({
    @NamedQuery(name="findCatalogAll", query="SELECT c FROM Catalog c"),
    @NamedQuery(name="findCatalogByJournal", 
        query="SELECT c FROM Catalog c WHERE c.journal = :journal")
  })

The entity class implements the Serializable interface to serialize a cache enabled entity bean to a cache when persisted to a database. To associate a version number with a serializable class by serialization runtime, specify a serialVersionUID variable.

private static final long serialVersionUID = 1L;

The Catalog entity includes variables id (primary key), journal of type String, and editions for the Edition entities associated with a Catalog entity.

private int id;
private String journal;
private List<Edition> editions;

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

The @Id annotation specifies the identifier property. The @Column annotation specifies the column name associated with the property. The nullable element is set to false as the primary key is not nullable. As we selected the primary key generator to be of the type sequence, the @SequenceGenerator annotation is specified with a sequence name. The generation strategy is specified with the @GeneratedValue annotation. The getter and setter methods for the identifier property are also specified.

@Id
@Column(name="ID", nullable=false)
@SequenceGenerator(name="CATALOG_ID_GENERATOR", sequenceName="CATALOG_SEQ",allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CATALOG_ID_GENERATOR")
  public int getId() {
    return this.id;
  }
  public void setId(int id) {
    this.id = id;
  }

Similarly, specify getter and setter methods for the journal property. The @OneToMany annotation specifies the bi-directional many-to-one association to Edition. The mappedBy element is specified on the non-owning side of the relationship, which is the Catalog entity. The cascade element is set to ALL as we discussed earlier. The fetch element is set to EAGER. A join table is included on the non-owning side to initiate cascade operations using the @JoinTable annotation. The join columns are specified using the @JoinColumn annotation. The getter and setter methods for the Edition collection are also specified.

@OneToMany(mappedBy="catalog", cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
  @JoinTable(name="CATALOGEDITIONS", 
    joinColumns=
        @JoinColumn(name="catalogId", referencedColumnName="ID"),
      inverseJoinColumns=
      @JoinColumn(name="editionId", referencedColumnName="ID")
      )
public List<Edition> getEditions() {
    return this.editions;
  }
public void setEditions(List<Edition> editions) {
    this.editions = editions;
  }

Methods addEdition and removeEdition are also included to add and remove Edition entities. For a more detailed discussion on entity beans refer to the EJB 3.0 Database Persistence with Oracle Fusion Middleware 11g book.

The Catalog entity class

The Catalog entity class is listed as follows:

package ejb3;

import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
 * The persistent class for the CATALOG database table.
 * 
 */
@Entity
@NamedQueries({
    @NamedQuery(name="findCatalogAll", query="SELECT c FROM Catalog c"),
    @NamedQuery(name="findCatalogByJournal", 
        query="SELECT c FROM Catalog c WHERE c.journal = :journal")
  })
public class Catalog implements Serializable {
  private static final long serialVersionUID = 1L;
  private int id;
  private String journal;
  private List<Edition> editions;

    public Catalog() {
    }
  @Id
  @Column(name="ID", nullable=false)
  @SequenceGenerator(name="CATALOG_ID_GENERATOR", sequenceName="CATALOG_SEQ",allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CATALOG_ID_GENERATOR")
  public int getId() {
    return this.id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getJournal() {
    return this.journal;
  }

  public void setJournal(String journal) {
    this.journal = journal;
  }

  //bi-directional many-to-one association to Edition
  @OneToMany(mappedBy="catalog", cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
  @JoinTable(name="CATALOGEDITIONS", 
    joinColumns=
        @JoinColumn(name="catalogId", referencedColumnName="ID"),
      inverseJoinColumns=
      @JoinColumn(name="editionId", referencedColumnName="ID")
      )
  public List<Edition> getEditions() {
    return this.editions;
  }

  public void setEditions(List<Edition> editions) {
    this.editions = editions;
  }
  public void addEdition(Edition edition) {
      this.getEditions().add(edition);
    }
    
    public void removeEdition(Edition edition) {
      this.getEditions().remove(edition);
    }
}

Creating the Edition entity

The Edition entity includes the named queries findEditionAll and findEditionBySection. The class specifies variables serialVersionUID, id, edition, catalog, and sections. As in the Catalog entity, id is the identifier property. The bi-directional many-to-one association to the Catalog relationship is specified using the @ManyToOne annotation. The Edition entity is the owning side of the relationship. A bi-directional many-to-one association to Section is also specified. Add and remove methods for the Catalog and Section entities are also specified. The discussion that applies to the Catalog entity also applies to the other entities, and has been omitted here for the other entities.

The Edition entity class

The Edition entity is listed as follows:

package ejb3;

import java.io.Serializable;
import javax.persistence.*;

import java.util.List;
/**
 * The persistent class for the EDITION database table.
 * 
 */
@Entity
@NamedQueries( { @NamedQuery(name = "findEditionAll",
        query = "SELECT e FROM Edition e")
,
@NamedQuery(name = "findEditionByEdition", query = "SELECT e from Edition e WHERE e.edition = :edition")
} )
public class Edition implements Serializable {
  private static final long serialVersionUID = 1L;
  private int id;
  private String edition;
  private Catalog catalog;
  private List<Section> sections;

    public Edition() {
    }

  @Id
  @Column(name="ID", nullable=false)
  @SequenceGenerator(name="EDITION_ID_GENERATOR", sequenceName="EDITION_SEQ",allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EDITION_ID_GENERATOR")
  public int getId() {
    return this.id;
  }
  public void setId(int id) {
    this.id = id;
  }
  //bi-directional many-to-one association to Catalog
  @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
  @JoinTable(name = "EditionCatalog",
               joinColumns = { @JoinColumn(name = "editionId",referencedColumnName = "ID")
                } ,
inverseJoinColumns = { @JoinColumn(name = "catalogId", referencedColumnName ="ID")})
  public Catalog getCatalog() {
    return this.catalog;
  }
  public void setCatalog(Catalog catalog) {
    this.catalog = catalog;
  }
  
  //bi-directional many-to-one association to Section
  @OneToMany(mappedBy="edition", cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
  @JoinTable(name = "EditionSections",
               joinColumns = { @JoinColumn(name = "editionId",
                                           referencedColumnName = "ID")
                } ,
        inverseJoinColumns = { @JoinColumn(name = "sectionId", referencedColumnName =
                                           "ID")
                } )
  public List<Section> getSections() {
    return this.sections;
  }
  public void setSections(List<Section> sections) {
    this.sections = sections;
  }
  public void addSection(Section section) {
        this.getSections().add(section);
        section.setEdition(this);
    }
  public String getEdition() {
        return edition;
    }
    public void setEdition(String edition) {
        this.edition = edition;
    }
    public void removeSection(Section section) {
        this.getSections().remove(section);
    }
}

Creating the Section entity

The Section entity has the named queries findSectionAll and findSectionBySectionName, and the properties id, sectionname, articles, and edition. A bi-directional many-to-one association to Article and a bi-directional many-to-one association to Edition are specified. Add and remove methods for the Edition and Article entities are also specified.

The Section entity class

The Section entity is listed as follows:

package ejb3;

import java.io.Serializable;
import javax.persistence.*;
import java.util.List;


/**
 * The persistent class for the SECTION database table.
 * 
 */
@Entity
@NamedQueries({
    @NamedQuery(name="findSectionAll", query="SELECT s FROM Section s"),
    @NamedQuery(
      name="findSectionBySectionName", query="SELECT s from Section s WHERE s.sectionname = :section")
  })
public class Section implements Serializable {
  private static final long serialVersionUID = 1L;
  private int id;
  private String sectionname;
  private List<Article> articles;
  private Edition edition;

    public Section() {
    }
  @Id
  @Column(name="ID", nullable=false)
  @SequenceGenerator(name="SECTION_ID_GENERATOR", sequenceName="SECTION_SEQ",allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SECTION_ID_GENERATOR")
  public int getId() {
    return this.id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getSectionname() {
    return this.sectionname;
  }

  public void setSectionname(String sectionname) {
    this.sectionname = sectionname;
  }
  //bi-directional many-to-one association to Article
  @OneToMany(mappedBy="section", cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
  @JoinTable(name = "SectionArticles",
          joinColumns = {  
              @JoinColumn(name="sectionId", referencedColumnName="ID")},   
              inverseJoinColumns = { @JoinColumn(name="articleId", referencedColumnName="ID")})
  public List<Article> getArticles() {
    return this.articles;
  }
  public void setArticles(List<Article> articles) {
    this.articles = articles;
  }
  //bi-directional many-to-one association to Edition
  @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
  @JoinTable(name = "SectionEdition",
               joinColumns = { @JoinColumn(name = "sectionId",
                                           referencedColumnName = "ID")
                } ,
        inverseJoinColumns = { @JoinColumn(name = "editionId", referencedColumnName =
                                           "ID")
                } )
  
  public Edition getEdition() {
    return this.edition;
  }
  public void setEdition(Edition edition) {
    this.edition = edition;
  }
  public void addArticle(Article article) {
        this.getArticles().add(article);
        article.setSection(this);
    }
  public void removeArticle(Article article) {
        this.getArticles().remove(article);
    }
}

Creating the Article entity

The Article entity has a named query findArticleAll, and the properties id, title, and section. A bi-directional many-to-one association to Section is also defined.

The Article entity class

The Article entity is listed as follows:

package ejb3;

import java.io.Serializable;
import javax.persistence.*;
/**
 * The persistent class for the ARTICLE database table.
 * 
 */
@Entity
@NamedQueries({
    @NamedQuery(name="findArticleAll", query="SELECT a FROM Article a"),
    @NamedQuery(
      name="findArticleByTitle", query="SELECT a from Article a WHERE a.title = :title")
  })
public class Article implements Serializable {
  private static final long serialVersionUID = 1L;
  private int id;
  private String title;
  private Section section;

    public Article() {
    }

  @Id
  @Column(name="ID", nullable=false)
  @SequenceGenerator(name="ARTICLE_ID_GENERATOR", sequenceName="ARTICLE_SEQ",allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ARTICLE_ID_GENERATOR")
  public int getId() {
    return this.id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getTitle() {
    return this.title;
  }

  public void setTitle(String title) {
    this.title = title;
  }


  //bi-directional many-to-one association to Section
  @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
  @JoinTable(name = "ArticleSection",
        joinColumns = {  
            @JoinColumn(name="articleId", referencedColumnName="ID")},   
            inverseJoinColumns = { @JoinColumn(name="sectionId", referencedColumnName="ID")})

  public Section getSection() {
    return this.section;
  }
  public void setSection(Section section) {
    this.section = section;
  }
  
}

In the Project Explorer, the entity beans will show some errors if the sequences or join tables have not yet been created.

Creating the JPA persistence configuration file

The persistence.xml configuration file specifies a persistence provider to be used for persisting the entities to the database. The persistence unit is specified using the persistence-unit element. The transaction-type is set to JTA by default. The persistence provider is specified as org.eclipse.persistence.jpa.PersistenceProvider. The jta-data-source element specifies the JTA data source. The entity classes are specified using the class element. The eclipselink.target-server property specifies the target server as WebLogic 10g. The eclipselink.target-database property specifies the target database as Oracle. The DDL generation strategy is set to create-tables using the eclipselink.ddl-generation property. Other EclipseLink properties (http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Sch) may also be specified as required. The persistence.xml configuration file is listed as follows:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="em" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/OracleDS</jta-data-source>
    <class>ejb3.Article</class>
    <class>ejb3.Catalog</class>
    <class>ejb3.Edition</class>
    <class>ejb3.Section</class>
    <properties>
      <property name="eclipselink.target-server" value="WebLogic_10"/>
      <property name="eclipselink.target-database" value="Oracle"/>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
      <property name="eclipselink.logging.level" value="FINEST"/>
    </properties>
  </persistence-unit>
</persistence>

The eclipselink.ddl-generation property may be set to create-tables or drop-and-create-tables, which drops tables if already created and creates new tables. In development the drop-and-create-tables may be used as the schema may need to be updated and data cleared. We have set eclipselink.ddl-generation to create-tables, which creates tables only if the tables are not already created. The JPA specification does not mandate the creating of tables and only some JPA persistence providers create tables. If it is not known whether a persistence provider supports table generation it is better to create the tables, sequences, and join tables as we have also set the eclipselink.ddl-generation value to create-tables.

 

Creating a session bean facade


For better performance, wrap the entity bean in a session bean facade. The performance benefits of a session facade are fewer remote method calls and an outer transaction context with which each getter method invocation does not start a new transaction. Session facade is one of the core Java EE design patterns (http://www.oracle.com/technetwork/java/sessionfacade-141285.html). To create a session bean, go to File | New | Other and select EJB|Session Bean (EJB 3.X) and click on Next as shown in the following screenshot:

Select the EJB project in which you want to create a session bean. The Source folder and package are the same as the folder for the entity classes. Specify Class name as CatalogSessionBeanFacade. Select the session bean State type as Stateless, which does not incur the overhead of keeping the state of the session bean. Select Remote for the Create business interface option and specify the remote class name as CatalogSessionBeanFacadeRemote. Now, click on Next as shown in the following screenshot:

Specify Mapped name as EJB3-SessionEJB, Transaction Type as Container. The mapped name is used to look up the session bean from a client. Now, click on Finish as shown in the following screenshot:

A session bean class and the remote business interface get created. The session bean class is annotated with the @Stateless annotation with name and mappedName elements.

@Stateless(name="CatalogSessionBean", mappedName="EJB3-SessionEJB")
public class CatalogSessionBeanFacade implements CatalogSessionBeanFacadeRemote { }

Next, we will modify the default session bean generated by the session bean wizard.

Creating an EntityManager

An EntityManager is used to create, remove, find, and query persistence entity instances. Inject an EntityManager, using the @PersistenceContext annotation. Specify the unitName as the unitName configured in persistence.xml.

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

Specifying getter methods

In this section, we shall specify getter methods for Collections of entities. For example, the getAllEditions method gets all Edition entities using the named query findEditionAll. The createNamedQuery method of EntityManager is used to create a Query object from a named query. Specify the TransactionAttribute annotation's TransactionAttributeType enum to REQUIRES_NEW, with which the EJB container invokes a session bean method with a new transaction context. REQUIRES_NEW has the advantage that if a transaction is rolled back due to an error in a different transaction context from which the session bean is invoked it does not effect the session bean that has the TransactionAttributeType set to REQUIRES_NEW.

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public List<Edition> getAllEditions() {
        ArrayList<Edition> editions = new ArrayList<Edition>();
        Query q = em.createNamedQuery("findEditionAll");
        for (Object ed : q.getResultList()) {
            editions.add((Edition)ed);
        }
        return editions;
    }

Creating test data

As we have EJB relationships between different entities, making modifications such as updating or deleting data would affect the associated entities. To demonstrate the use of the entities, we shall create some test data and subsequently delete the data. Create test data with the createTestData convenience method in the session bean. Alternatively, a unit test or an extension class may also be used. Create a Catalog entity and set the journal using the setJournal method. Persist the entity using the persist method of the EntityManager object and synchronize the entity with the database using the flush method.

Catalog catalog1 = new Catalog();
       catalog1.setId(1); 
        catalog1.setJournal("Oracle Magazine");
        em.persist(catalog1);
        em.flush();

Similarly, we can use the create, persist, and flush methods in an Edition entity object. Before adding the Edition object to the database merge the Catalog entity with the persistence context using the merge method.

Edition edition = new Edition();
        edition.setEdition("January/February 2009");
        em.persist(edition);

        em.flush();
        em.merge(catalog1);
        catalog1.addEdition(edition);

Similarly, add the Section and Article entity instances. Delete some data with the deleteSomeData method in which we shall create a Query object using the named query findArticleByTitle. Specify the article title using the setParameter method of the Query object. Get the result List using the getResultList method of the Query object. Iterate over the result List and remove the article using the remove method of the EntityManager object.

public void deleteSomeData() {
        // remove an article
      Query q = em.createNamedQuery("findArticleByTitle");
        q.setParameter("title", "Launching Performance");
        List list = q.getResultList();
        for (Object article : list) {
            em.remove(article);
        }
    }

Also, add remove<> methods to remove entities.

The session bean class

The session bean class is listed as follows:

package ejb3;

import javax.ejb.*;
import javax.persistence.*;
import java.util.*;

Annotate the session bean with the @Stateless annotation, which includes the mappedName used to look up the session bean from a client:

@Stateless(name = "CatalogSessionBean", mappedName = "EJB3-SessionEJB")
public class CatalogSessionBeanFacade implements CatalogSessionBeanFacadeRemote {
  @PersistenceContext(unitName = "em")
  EntityManager em;

Specify the getter collections methods for the different entities:

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public List<Edition> getAllEditions() {
    ArrayList<Edition> editions = new ArrayList<Edition>();
    Query q = em.createNamedQuery("findEditionAll");
    for (Object ed : q.getResultList()) {
      editions.add((Edition) ed);
    }
    return editions;
  }

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public List<Section> getAllSections() {
    ArrayList<Section> sections = new ArrayList<Section>();
    Query q = em.createNamedQuery("findSectionAll");
    for (Object ed : q.getResultList()) {
      sections.add((Section) ed);
    }
    return sections;
  }

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public List<Article> getAllArticles() {
    ArrayList<Article> articles = new ArrayList<Article>();
    Query q = em.createNamedQuery("findArticleAll");
    for (Object ed : q.getResultList()) {
      articles.add((Article) ed);
    }
    return articles;
  }

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public List<Catalog> getAllCatalogs() {

    Query q = em.createNamedQuery("findCatalogAll");
    List<Catalog> catalogs = q.getResultList();
    ArrayList<Catalog> catalogList = new ArrayList<Catalog>(catalogs.size());
    for (Catalog catalog : catalogs) {
      catalogList.add(catalog);
    }
    return catalogList;
  }
  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public List<Edition> getCatalogEditions(Catalog catalog) {
    em.merge(catalog);
    List<Edition> editions = catalog.getEditions();
    ArrayList<Edition> editionList = new ArrayList<Edition>(editions.size());
    for (Edition edition : editions) {
      editionList.add(edition);
    }
    return editionList;
  }

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public List<Section> getEditionSections(Edition edition) {
    em.merge(edition);
    List<Section> sections = edition.getSections();
    ArrayList<Section> sectionList = new ArrayList<Section>(sections.size());
    for (Section section : sections) {
      sectionList.add(section);
    }
    return sectionList;
  }

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public List<Article> getSectionArticles(Section section) {
    em.merge(section);
    List<Article> articles = section.getArticles();
    ArrayList<Article> articleList = new ArrayList<Article>(articles.size());
    for (Article article : articles) {
      articleList.add(article);
    }
    return articleList;
  }

Add a convenience method to create test data.

  public void createTestData() {
    // create catalog for Oracle Magazine
    Catalog catalog1 = new Catalog();
    // catalog1.setId(1);
    catalog1.setJournal("Oracle Magazine");
    em.persist(catalog1);
    em.flush();
    // Add an Edition
    Edition edition = new Edition();
    // edition.setId(2);
    edition.setEdition("January/February 2009");
    em.persist(edition);
    // em.refresh(edition);
    em.flush();
    em.merge(catalog1);
    catalog1.addEdition(edition);

    // Add a Features Section
    Section features = new Section();
    // features.setId(31);
    features.setSectionname("FEATURES");
    em.persist(features);
    em.merge(edition);
    edition.addSection(features);

    // add an article to Features section
    Article article = new Article();
    // article.setId(41);
    article.setTitle("Launching Performance");
    article.setSection(features);
    em.persist(article);
    em.merge(features);
    features.addArticle(article);
    em.flush();

    // add a Technology section
    Section technology = new Section();
    // technology.setId(32);
    technology.setSectionname("Technology");
    em.persist(technology);
    em.merge(edition);
    edition.addSection(technology);
    // add an article to Technology section
    article = new Article();
    // article.setId(42);
    article.setSection(technology);
    article.setTitle("On Dynamic Sampling");
    em.persist(article);
    em.merge(technology);
    technology.addArticle(article);
    em.flush();
  }

Add another convenience method to delete some data.

  public void deleteSomeData() {
    // remove an article
    Query q = em.createNamedQuery("findArticleByTitle");
    q.setParameter("title", "Launching Performance");
    List list = q.getResultList();
    for (Object article : list) {
      em.remove(article);
    }
  }

Add some remove<Entity> methods to remove entities:

  public void removeEdition(Edition edition) {
    Catalog catalog = edition.getCatalog();
    catalog.removeEdition(edition);

    em.remove(edition);
  }

  public void removeSection(Section section) {
    Edition edition = section.getEdition();
    edition.removeSection(section);
    em.remove(section);
  }

  public void removeArticle(Article article) {
    Section section = article.getSection();
    section.removeArticle(article);
    em.remove(article);
  }
}

The remote business interface

The remote business interface is listed as follows:

package ejb3;

import javax.ejb.*;
import java.util.*;

@Remote
public interface CatalogSessionBeanFacadeRemote {
  public List<Edition> getAllEditions();

  public List<Section> getAllSections();

  public List<Article> getAllArticles();

  public List<Catalog> getAllCatalogs();

  public List<Edition> getCatalogEditions(Catalog catalog);

  public List<Section> getEditionSections(Edition edition);

  public List<Article> getSectionArticles(Section section);

  public void createTestData();

  public void deleteSomeData();

  public void removeEdition(Edition edition);

  public void removeSection(Section section);

  public void removeArticle(Article article);
}
 

Creating the application.xml descriptor


We also need to create an application.xml deployment descriptor to generate an EAR application to be deployed to the WebLogic Server. First, create a META-INF folder by going to File | New | Folder. Subsequently, create an XML file going to File | New | Other and then click on XML | XML File in the New wizard. Click on Next.

Specify the META-INF folder and specify the filename as application.xml. Click on Next as shown in the following screenshot:

Click on Create an XML file from an XML template and then click on Next. In Select XML Template, select the checkbox Use XML Template. Select the xml declaration in the XML Template and click on Finish. An application.xml file gets added to the META-INF folder. Specify an EJB module and a web module in the deployment descriptor. The application.xml descriptor is listed as follows:

<?xml version="1.0" encoding="UTF-8"?>
<application>
  <display-name></display-name>
  <module>
    <ejb>ejb3example.jar</ejb>
  </module>
  <module>
    <web>
      <web-uri>weblogicexample.war</web-uri>
      <context-root>weblogic</context-root>
    </web>
  </module>
</application>

The following screenshot shows application.xml in the EJB project:

 

Creating a test client


Next, we shall create a JSP client to test the entity bean. We shall look up the session bean using the global JNDI name, which includes the mapped name for the session bean. Subsequently, we shall invoke the testData method of the session bean to test database persistence using the entity bean. First, create a JSP file. Create a webModule folder for the JSP file by going to File | New | Folder. Specify Folder name as webModule in the EJB3JPA folder and click on Finish. Go to File | New | Other and select JSP File in Web and click on Next. Specify JSP File name as catalog.jsp and click on Next as shown in the following screenshot:

Select the New JSP File (html) template and click on Finish. A JSP client catalog.jsp gets created. Create an InitialContext object.

InitialContext context = new InitialContext();

Look up the remote business interface of the session bean using the global JNDI name:

CatalogSessionBeanFacadeRemote beanRemote = (CatalogSessionBeanFacadeRemote) context.lookup("EJB3-SessionEJB#ejb3.CatalogSessionBeanFacadeRemote");

Invoke the createTestData method and retrieve the List of Catalog entities:

beanRemote.createTestData();
List<Catalog> catalogs=beanRemote.getAllCatalogs();

Iterate over the Catalog entities and output the catalog ID, journal name. Similarly, obtain the Entity, Section, and Article entities and output the entity property values.

The catalog.jsp file

The catalog.jsp file is listed as follows:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ page import="ejb3.*,java.util.*,javax.naming.*"%>
<html>
<head>
<meta http-equiv="Content-Type"
  content="text/html; charset=windows-1252" />
<title>EJB3 Client</title>
</head>
<body>

Create an InitialContext method to look up the session bean facade:

  <%
    InitialContext context = new InitialContext();
    CatalogSessionBeanFacadeRemote beanRemote = (CatalogSessionBeanFacadeRemote) context
        lookup("EJB3-SessionEJB#ejb3.CatalogSessionBeanFacadeRemote"); 

Invoke the session bean method to create test data. Subsequently, retrieve the entity beans and output the values of entities' properties:

    beanRemote.createTestData();
    List<Catalog> catalogs = beanRemote.getAllCatalogs();

    out.println("<br/>" + "List of Catalogs" + "<br/>");
    for (Catalog catalog : catalogs) {
      out.println("Catalog Id:");
      out.println("<br/>" + catalog.getId() + "<br/>");
      out.println("Catalog Journal:");
      out.println(catalog.getJournal() + "<br/>");
    }

    out.println("<br/>" + "List of Editions" + "<br/>");
    List<Edition> editions = beanRemote.getAllEditions();
    for (Edition edition : editions) {
      out.println("Edition Id:");
      out.println(edition.getId() + "<br/>");
      out.println("Edition Date:");
      out.println(edition.getEdition() + "<br/>");
    }
    out.println("<br/>" + "List of Sections" + "<br/>");
    List<Section> sections = beanRemote.getAllSections();
    for (Section section : sections) {
      out.println("Section Id:");
      out.println(section.getId() + "<br/>");
      out.println("Section Name:");
      out.println(section.getSectionname() + "<br/>");

    }

    out.println("<br/>" + "List of Articles" + "<br/>");
    List<Article> articles = beanRemote.getAllArticles();
    for (Article article : articles) {
      out.println("Article Id:");
      out.println(article.getId() + "<br/>");
      out.println("Article Title:");
      out.println(article.getTitle() + "<br/>");

    }
    out.println("Delete some Data" + "<br/>");

Invoke the session bean method to delete some data. Subsequently, retrieve the entities and output the properties of different entities:

    beanRemote.deleteSomeData();

    catalogs = beanRemote.getAllCatalogs();
    out.println("<br/>" + "List of Catalogs" + "<br/>");
    for (Catalog catalog : catalogs) {
      out.println("Catalog Id:");
      out.println(catalog.getId() + "<br/>");
      out.println("Catalog Journal:");
      out.println(catalog.getJournal() + "<br/>");
    }

    out.println("<br/>" + "List of Editions" + "<br/>");
    editions = beanRemote.getAllEditions();
    for (Edition edition : editions) {
      out.println("Edition Id:");
      out.println(edition.getId() + "<br/>");
      out.println("Edition Date:");
      out.println(edition.getEdition() + "<br/>");

    }
    out.println("<br/>" + "List of Sections" + "<br/>");
    sections = beanRemote.getAllSections();
    for (Section section : sections) {
      out.println("Section Id:");
      out.println(section.getId() + "<br/>");
      out.println("Section Name:");
      out.println(section.getSectionname() + "<br/>");

    }
    out.println("<br/>" + "List of Articles" + "<br/>");
    articles = beanRemote.getAllArticles();
    for (Article article : articles) {
      out.println("Article Id:");
      out.println(article.getId() + "<br/>");
      out.println("Article Title:");
      out.println(article.getTitle() + "<br/>");
    }
  %>
</body>
</html>
 

Packaging and deploying the entity bean application


In this section, we shall compile, package, and deploy the EJB application to the WebLogic server using an Ant build file. First, add the web.xml deployment descriptor. Create a WEB-INF folder in the webModule folder and add web.xml to the WEB-INF folder. The web.xml is an optional deployment descriptor for a web application deployed to the WebLogic descriptor and is listed as follows:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee/web- app_2_5.xsd" version="2.5">
</web-app>

If we were using servlets or other web application artifacts, we would have configured those in web.xml. We need a build.xml file for the tasks involved in assembling and deploying the entity bean application. Create a build.xml file in the project EJB3JPA by going to File | New | Other and in the New wizard, in XML, select XML file. Specify the following properties in the build.xml file:

Property

Value

Description

src.dir

${basedir}/ejbModule

Source directory

web.module

${basedir}/webModule

Web module directory

weblogic.home

C:/Oracle/Middleware

WebLogic home directory

weblogic.server

${weblogic.home}/wlserver_12.1/server

WebLogic Server directory

build.dir

${basedir}/build

Build directory

deploy.dir

${weblogic.home}/user_projects/domains/base_domain/autodeploy

Deploy directory

Specify a path element to include the WebLogic JAR files. Add the following tasks in the build file:

Task

Description

prepare

Makes the required directories

compile

Compiles the Java classes

jar

Creates a EJB JAR

war

Creates a web application WAR file

assemble-app

Assembles the JAR and the WAR files into an EAR file

deploy

Deploy the EAR file to WebLogic server

clean

Deletes directories when recompiling

The build script

The build.xml file is listed as follows:

<?xml version="1.0" encoding="UTF-8"?>
  <!--
    WebLogic build file
  -->

First, declare the different properties used in the build script:

<project name="EJB3" default="deploy" basedir=".">
  <property environment="env" />
  <property name="src.dir" value="${basedir}/ejbModule" />
  <property name="web.module" value="${basedir}/webModule" />
    <property name="weblogic.home" value="C:/Oracle/Middleware/" />
  <property name="weblogic.server" value="${weblogic.home}/wlserver_12.1/server" />  <property name="build.dir" value="${basedir}/build" />

  <property name="deploy.dir"
    value="${weblogic.home}/user_projects/domains/base_domain/autodeploy" />

Specify the class path for the classes to be compiled:

  <path id="classpath">
    <fileset dir="${weblogic.home}/modules">
      <include name="*.jar" />
    </fileset>
    <fileset dir="${weblogic.server}/lib">
      <include name="*.jar" />
    </fileset>

    <pathelement location="${build.dir}" />
  </path>
  <property name="build.classpath" refid="classpath" />
  <target name="prepare">
    <mkdir dir="${build.dir}" />
  </target>    

Compile the Java classes, which include the entity beans and the session bean facade:

  <target name="compile" depends="prepare">
    <javac srcdir="${src.dir}" destdir="${build.dir}" debug="on"
      includes="**/*.java">
      <classpath refid="classpath" />
    </javac>
  </target>

Generate the EJB JAR file, which includes the compiled EJB classes and the deployment descriptors:

  <target name="jar" depends="compile">
    <jar destfile="${build.dir}/ejb3.jar">
      <fileset dir="${build.dir}">
        <include name="**/*.class" />
      </fileset>
      <fileset dir="${src.dir}">
        <include name="META-INF/*.xml" />
      </fileset>
    </jar>
  </target>

Generate the web application WAR file, which includes the JSP client:

  <target name="war" depends="jar">
    <war warfile="${build.dir}/weblogic.war">
      <fileset dir="webModule">
        <include name="*.jsp" />
      </fileset>
      <fileset dir="webModule">
        <include name="WEB-INF/web.xml" />
      </fileset>
    </war>
  </target>

Assemble the application into an EAR file, which includes the EJB JAR and the WAR files and the application.xml deployment descriptor:

  <target name="assemble-app" depends="war">
    <jar jarfile="${build.dir}/ejb3.ear">
      <metainf dir="META-INF">
        <include name="application.xml" />
      </metainf>
      <fileset dir="${build.dir}" includes="*.jar,*.war" />
    </jar>
  </target>

Deploy the application to the WebLogic Server deploy directory, the autodeployed directory:

  <target name="deploy" depends="assemble-app">
    <copy file="${build.dir}/ejb3.ear" todir="${deploy.dir}" />
  </target>
  <target name="clean">
    <delete file="${build.dir}/ejb3.ear" />
    <delete file="${build.dir}/ejb3.jar" />
    <delete file="${build.dir}/weblogic.war" />
  </target>
</project>

Running the build script

Having created a build script, now we shall run it. Right-click on build.xml and select Run As | Ant Build as shown in the following screenshot:

Select the deploy task and click on Run as shown in the following screenshot. As dependence is declared between tasks all the preceding tasks will also get run.

The EJB application gets compiled, built, assembled, and deployed to WebLogic Server's autodeployed directory as an EAR file. The BUILD SUCCESSFUL message indicates that the build and deployment was without error. If the build needs to be re-run first run the clean task, which deletes any previously generated EAR, WAR, and JAR files.

Start the WebLogic Server if not already started. In the WebLogic Server's Admin Server Console, the EAR file is shown deployed in Deployments. On expanding the EAR file the EJB JAR and web module WAR get listed as shown in the following screenshot:

 

Testing the JSP client


Next, we shall run the JSP client to invoke the session bean facade, which subsequently invokes the entity beans. Test the JSP client with the URL http://localhost:7001/weblogic/catalog.jsp. The test data gets generated and the entity properties get listed for the Catalog, Edition, Section, and Article entities as shown in the following screenshot:

 

Summary


In this chapter, we discussed creating an EJB project using the EJB 3.0 Module project facet provided by the Oracle Enterprise Pack for Eclipse. To create an entity bean, we added the JPA project facet. Subsequently, we generated entity beans from tables. We created a session bean facade for the entity beans; wrapping an entity bean in a session bean facade is a best practice. We created a JSP client for the EJB application. We packaged and deployed the EJB application to WebLogic Server and ran the test client on the WebLogic Server.

In the next chapter, we will discuss the Object/XML (O/X) mapping provided by the JAXB 2.0 framework using the Oracle WebLogic web services project facet.

About the Author

  • Deepak Vohra

    Deepak Vohra is consultant and principle a member of the NuBean software company. He is a Sun Certified Java Programmer (SCJP) and Sun Certified Web Component Developer (SCWCD) and has worked in the fields of XML, Java programming, and J2EE for over 10 years. He is the coauthor of the Apress book Pro XML Development with Java Technology. Deepak is the author of several Packt Publishing books, including Processing XML documents with Oracle JDeveloper 11g and Java EE Development with Eclipse. Deepak is also a Docker Mentor and has published four other Docker-related books.

    Browse publications by this author

Latest Reviews

(1 reviews total)
Excellent