Book Image

Java EE Development with Eclipse

By : Deepak Vohra
Book Image

Java EE Development with Eclipse

By: Deepak Vohra

Overview of this book

<p>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.<br /><br />"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.<br /><br />"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. <br /><br />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.</p>
Table of Contents (17 chapters)
Java EE Development with Eclipse
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

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.