EJB Entity bean example

ejb entity bean life cycle and ejb entity bean tutorial
JohenCorner Profile Pic
JohenCorner,France,Professional
Published Date:02-08-2017
Your Website URL(Optional)
Comment
Creating EJB 3.0 Entity Relationships So far, we have discussed only the simple-case entity beans in which a single entity bean is mapped to a single database table. No book on EJB 3.0 is complete without a discussion of relationships between multiple entity beans with each bean mapped to a different database table. Multiple entity beans and multiple database tables become essential when it is not feasible to define all the entities in a single entity bean and a single database table. In this chapter, we shall discuss an example of multiple entity beans with relationships between them. We shall learn the following: • Creating database tables • Mapping the database tables to entity classes • Creating a wrapper session bean • Creating a client JSP for the entity bean application • Testing the client • Demonstrating the effect of modifying the fetch strategy But, first we shall review the different metadata annotations provided for EJB 3.0 entity relationships. aCreating EJB 3.0 Entity Relationships EJB 3.0 entity relationship annotations The Java Persistence API provides metadata annotations for EJB 3.0 entity relationships. The different types of EJB 3.0 relationships that may be den fi ed are discussed in the following table: Annotation Description Annotation Elements OneToOne Defines a single-valued targetEntity (optional): This is association to another entity. the entity class that is the target of the The association has one-to- association. one multiplicity. cascade(optional): The operations that must be cascaded to the target of the association. By default, no operations are cascaded. fetch(optional): This specifies whether the association should be lazily loaded or eagerly fetched. The default isEAGER. mappedBy(optional): This is the field that owns the relationship. ThemappedBy element is specified on the non-owning side of the relationship. optional(optional): This specifies if the relationship is optional. If set to false, non-null relationships must always exist. By default, it is true. OneToMany Defines a many-valued targetEntity (optional): The entity association with one-to- class that is the target of the association. many multiplicity. cascade (optional): This specifies the operations that must be cascaded to the target of the association. By default, no operations are cascaded. fetch(optional): This specifies the fetch strategy. By default, it is LAZY. mappedBy: Specifies the field that owns the relationship. It isn't required unless the relationship is unidirectional. In a unidirectional relationship, only one entity has a reference to the other. In a bidirectional relationship, both entities have references to each other. 208 aChapter 7 Annotation Description Annotation Elements ManyToOne Defines a single-valued targetEntity (optional): This is association to another entity the entity class that is the target of the class that has many-to-one association. multiplicity. cascade (optional): These are the operations that must be cascaded to the target of the association. By default no operations are cascaded. fetch(optional): The fetch strategy. By default, the value isEAGER. optional(optional): Specifies whether the association is optional. By default, the value is true. ManyToMany Defines a many-valued targetEntity (optional): This is association with many-to- the entity class that is the target of the many multiplicity. association. If the collection is defined using generics the target entity is not required to be specified. cascade (optional): These are the operations that must be cascaded to the target entity. By default, no operations are cascaded. fetch (optional): This is the fetch strategy. By default, it isLAZY. mappedBy (optional): Specified on the non-owning side, the field that owns the relationship. Required unless the relationship is unidirectional. 209 aCreating EJB 3.0 Entity Relationships The Java Persistence API defines some other relationship annotations for mapping EJB 3.0 entity relationships. These annotations are discussed in the following table: Annotation Description Annotation Elements JoinTable This specifies the join table name(optional): The name of for mapping of associations. the join table. The default join table name catalog(optional): The is the table names of the catalog of the table. associated primary tables concatenated together schema(optional): The (owning-side first) using schema of the table. an underscore. Specified on the owning side of a many- joinColumns(optional): to-many association or in a The foreign key columns unidirectional one-to-many of the join table that association. reference the primary table of the entity owning the association. inverseJoinColumns (optional): The foreign key columns of the join table that reference the primary table of the non-owning entity. uniqueConstraints (optional): Unique constraints on the table. JoinColumns This defines composite value(optional): This foreign keys. Groups specifies an array of JoinColumn annotations JoinColumn . for a relationship. Thename and referencedColumnName elements must be specified for each of the JoinColumn. 210 aChapter 7 Annotation Description Annotation Elements JoinColumn Specifies a mapped column name(optional): The name for joining an association. of the foreign key column. If the join is for OneToOne or ManyToOne, the foreign key column is in the source entity. If the join is for a ManyToMany, the foreign key is in the join table. referencedColumnName (optional): The name of the column referenced by the foreign key column. unique (optional): Specifies if the property is a unique key. Default value is false. nullable (optional): Specifies if the foreign key column is nullable. Default value is true. insertable (optional): Specifies if the column is included in the SQLINSERT statements generated by the persistence provider. Default is true. updatable (optional): Specifies if the column is included in the SQLUPDATE statements generated by the persistence provider. Default is true. columnDefinition (optional): The SQL fragment used to generate the DDL for the column. table (optional): The name of the table that contains the column. Default is the primary table of the applicable entity. 211 aCreating EJB 3.0 Entity Relationships Annotation Description Annotation Elements MapKey Defines the map key for name (optional): The name associations of type java. of the persistent field or util.Map. property of the associated entity that is used as the map key. PrimaryKey Defines composite foreign value (optional): JoinColumns keys. Specifies one or more PrimaryKeyJoinColumn annotations. PrimaryKeyJoinColumn Specifies a primary key name (optional): The name column that is used as a of the primary key column of foreign key column to join the current table. to another table. referencedColumnName (optional): This is the name of the primary key column of the table being joined to. columnDefinition (optional): The SQL fragment used to generate the DDL for the column. Setting the environment We shall be using the WebLogic server integrated with JDeveloper 11g. Download and install JDeveloper 11g Studio edition (http://www.oracle.com/technology/ software/products/middleware/index.html). We also need to download and install Oracle database (http://www.oracle.com/technology/software/ products/database/index.html). Include the sample schemas when installing Oracle database. As we are using multiple entity beans, we need to create some database tables to which the entity beans are mapped. Creating database tables Create tablesCATALOG,EDITION,SECTION, andARTICLE with the following SQL scripts: 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)); 212 aChapter 7 Creating an EJB project First, we need to create an EJB project in JDeveloper 11g. Click on New Application. In the Create Java EE Web Application window, specify an Application Name (EJB3Rels), select the Java EE Web Application template, and click on Next. In the Name your View and Controller Project window, specify a Project Name (JSPViewController), select the EJB project technology, and click on Next. 213 aCreating EJB 3.0 Entity Relationships Select the default settings in the Configure Java Settings for the View window and click on Next. Select the default EJB Settings for the View and click on Next. In the Name your Model Project window, specify a model project name (EJB3Model) and click on Next. Select the default settings in the Configure Java Settings for the Model window and click on Next. In the Configure EJB Settings for the Model window , select EJB Version as EJB 3.0, select Using Annotations, and click on Finish. 214 aChapter 7 An EJB3 project gets added to the Application navigator tab in JDeveloper, as shown next: Creating the entity beans Next, we shall map the database tables that we created to the entity beans. But, before we may generate the entity beans from tables, we need a database connection. Using the procedure explained in some of the earlier chapters, create a database connection (OracleDBConnection) to an Oracle database. 215 aCreating EJB 3.0 Entity Relationships Select the project properties for the EJB3Model project and select the EJB Module node. The data source name corresponding to the OracleDBConnection is jdbc/ OracleDBConnectionDS. To create the entity beans from tables select File New, and in the New Gallery window, select Business Tier EJB in Categories and Entities from Tables in the Items header, as shown in the following screenshot. Click on OK. 216 aChapter 7 Click on New in the Persistence Unit window. In the New Persistence Unit window, specify a persistence unit name (em), and specify a JTA Datasource Name, which is the datasource we created earlier. When we use a JTA datasource with transaction type JTA (the default), the transactions are managed by the EJB container. The em persistence unit gets added to the Persistence Unit window. Click on Next. 217 aCreating EJB 3.0 Entity Relationships In the Type of Connection window, select Online Database Connection and click on Next. In the Database Connection Details window, select the OracleDBConnection and click on Next. In the Select Tables window, select the OE Schema and check the Auto Query checkbox. From the tables listed, select the CATALOG, EDITION, SECTION, and ARTICLE tables. Click on Next. Select the default settings in the General Options window. In the Specify Entity Details window, specify the Entity Name and Entity Class for the OE.Article table. The other tables are automatically mapped using the same pattern. Click on Next. 218 aChapter 7 The Summary page displays the entity beans that will be created from the database tables. Click on Finish. The entity beans Article, Section, Edition, and Catalog get created in the EJB3Model project. 219 aCreating EJB 3.0 Entity Relationships Select the EJB3Model project node and select Tools Project Properties. Select the Libraries and Classpath node. The EJB 3.0 library should be in the classpath. The Entity classes Next, we shall construct the entity beans created; we shall add the required NamedQueries and EJB 3.0 entity relationship mappings. The Catalog entity class TheCatalog entity bean has propertiesid andjournal, as shown below: private int id; private String journal; In theCatalog entity addNamedQueries findCatalogAll(), which selects all the Catalog entity instances andfindCatalogByJournal(), which selects aCatalog entity by journal name. NamedQueries( NamedQuery(name="findCatalogAll", query="SELECT c FROM Catalog c"), NamedQuery(name="findCatalogByJournal", query="SELECT c FROM Catalog c WHERE c.journal = :journal") ) 220 aChapter 7 TheCatalog entity has a many-to-many relationship with theEdition entity. We shall make theCatalog entity the owning-side of the relationship. The join table is defined on the owning side and cascade operations may be initiated only from the owning side. Specify theManyToMany annotation in theCatalog entity with cascade element set toALL, as we want to cascade all changes to the associated Edition entities when aCatalog entity is deleted. Setting cascading toALL does degrade performance slightly, as extra queries are required to be created, but cascading propagates modifications to the associated entities. ManyToMany(cascade=CascadeType.ALL) JoinTable(name="CATALOGEDITIONS", joinColumns=JoinColumn( name="catalogId", referencedColumnName="ID"), inverseJoinColumns= JoinColumn(name="editionId", referencedColumnName="ID")) The join table,CATALOGEDITIONS, is generated by the EJB container when the EJB is deployed to the server; therefore, we don't need to generate the join table. The join columncatalogId references the primary key id of theCATALOG table, and the inverse join columneditionId references the primary key id of theEDITION table. Thecascade element is set toALL, which implies that all operations are cascaded. TheCatalog entity bean class is listed next: package model; import java.io.Serializable; import javax.persistence.; import java.util.; 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 static final long serialVersionUID = 1; private int id; private String journal; private ListEdition editions; Id GeneratedValue 221 aCreating EJB 3.0 Entity Relationships public int getId() return id; public void setId(int id) this.id = id; public String getJournal() return journal; public void setJournal(String journal) this.journal = journal; ManyToMany(cascade=CascadeType.ALL) JoinTable(name="CATALOGEDITIONS", joinColumns=JoinColumn( name="catalogId", referencedColumnName="ID"), inverseJoinColumns=JoinColumn( name="editionId", referencedColumnName="ID") ) public ListEdition getEditions() return editions; public void setEditions(ListEdition editions) this.editions = editions; public void addEdition(Edition edition) this.getEditions().add(edition); public void removeEdition(Edition edition) this.getEditions().remove(edition); 222 aChapter 7 The Edition entity class TheEdition entity bean has the propertiesid andedition: private int id; private String edition; TheEdition entity defines a NamedQueries findEditionAll() (which finds all the Edition instances) andfindEditionByEdition() (which finds an Edition by the edition date): NamedQueries( NamedQuery(name = "findEditionAll", query = "SELECT e FROM Edition e"), NamedQuery(name = "findEditionByEdition", query = "SELECT e from Edition e WHERE e.edition = :edition") ) TheEdition entity is on the non-owning side of a bidirectional many-to-many relationship with theCatalog entity. Therefore, we specify theManyToMany annotation with themappedBy element. We don't need to specify a join table, as Edition entity is the non-owning side. Thecascade element is set to cascadeMERGE, PERSIST, andREFRESH operations: ManyToMany(cascade = CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH , mappedBy = "editions") protected ListCatalog getCatalogs() return catalogs; Theeditions field is defied in the Catalog entity, which is the owning side of the relationship. TheEdition entity also has a one-to-many relationship with the SECTION entity. In a one-to-many relationship the many side is made the owning side; therefore, the many side has the join table. But, a join table may be added on the one side also to initiate cascade operations from the one side. Therefore, we have added a join table on the one side (Edition entity) also: OneToMany(cascade = CascadeType.ALL, mappedBy = "edition") JoinTable(name = "EditionSection", joinColumns = JoinColumn( name = "editionId", referencedColumnName = "ID") , inverseJoinColumns = JoinColumn( name = "sectionId", referencedColumnName ="ID") ) 223 aCreating EJB 3.0 Entity Relationships public ListSection getSections() return sections; TheEdition entity class is listed next: package model; import java.io.Serializable; import javax.persistence.; import java.util.; 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 static final long serialVersionUID = 2; private String edition; private int id; private ListCatalog catalogs; private ListSection sections; ManyToMany(cascade = CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH , mappedBy = "editions") protected ListCatalog getCatalogs() return catalogs; protected void setCatalogs(ListCatalog catalogs) this.catalogs = catalogs; OneToMany(cascade = CascadeType.ALL, mappedBy = "edition", fetch = FetchType.EAGER) JoinTable(name = "EditionSection", joinColumns = JoinColumn( name = "editionId", referencedColumnName = "ID") , inverseJoinColumns = JoinColumn( name = "sectionId", referencedColumnName = "ID") ) public ListSection getSections() 224 aChapter 7 return sections; public void setSections(ListSection sections) this.sections = sections; public void addSection(Section section) this.getSections().add(section); section.setEdition(this); Id GeneratedValue public int getId() return id; public void setId(int id) this.id = id; public String getEdition() return edition; public void setEdition(String edition) this.edition = edition; public void removeSection(Section section) this.getSections().remove(section); The Section entity class TheSection entity has propertiesid andsectionName: private String id; private String sectionName; TheSection entity defines NamedQueries findSectionAll, which finds all the Section entities, andfindSectionBySectionName, which finds a Section entity by section name: NamedQueries( NamedQuery(name="findSectionAll", query="SELECT s FROM Section s"), NamedQuery(name="findSectionBySectionName", query="SELECT s from Section s WHERE s.sectionName = :section") ) 225 aCreating EJB 3.0 Entity Relationships TheSection entity is on the owning side (many side) of a many-to-one relationship with theEdition entity. Specify aManyToOne annotation with aJoinTable annotation. Thecascade element is set to cascadeMERGE,PERSIST, and REFRESH operations: ManyToOne(cascade=CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH) JoinTable(name = "SectionEdition", joinColumns = JoinColumn( name = "sectionId",referencedColumnName = "ID") , inverseJoinColumns = JoinColumn( name = "editionId", referencedColumnName ="ID") ) public Edition getEdition() return edition; TheSection entity also has a one-to-many relationship with theArticle entity. The Section entity is the non-owning side of the one-to-many relationship, but to be able to initiate cascade operations from theSection entity, we shall add a join table on theSection entity side. Thesection field specified in the mappedBy element is defined in the Article entity class: OneToMany(cascade=CascadeType.ALL,mappedBy = "section") JoinTable(name = «SectionArticle», joinColumns = JoinColumn(name=»sectionId», referencedColumnName=»ID»), inverseJoinColumns = JoinColumn( name=»articleId», referencedColumnName=»ID»)) public ListArticle getArticles() return articles; TheSection entity is listed next: package model; import java.io.Serializable; import java.util.List; import javax.persistence.; Entity NamedQueries( NamedQuery(name="findSectionAll", query="SELECT s FROM Section s"), NamedQuery( name="findSectionBySectionName", 226 a