EJB in Java

how to create ejb application in eclipse and how to write ejb program in eclipse
JohenCorner Profile Pic
JohenCorner,France,Professional
Published Date:02-08-2017
Your Website URL(Optional)
Comment
Using JSF with Entity Relationships In Chapter 7, Creating EJB 3.0 Entity Relationships, we discussed creating one-to-many and many-to-many relationships between entity EJBs. We added data by hard coding the data in the session bean. However, hardcoded data is rarely what is required. In this chapter, we shall create EJB 3.0 entity relationships and add data from JSF user interfaces. JSF UIs are the most commonly used interfaces for inputting data. JSF provides a range of UI components including select lists and event handling for those components. JSF also has the provision to create custom components. In this chapter, we shall discuss the following: • Creating Oracle database tables • Creating entity beans from database tables • Creating theEdition,Section, andArticle entities • Creating a session bean façade • Creating JSF user interfaces for creating entities and mapping entity relationships • Adding JSF components to the user interfaces • Defining managed beans for the JSF user interfaces • Adding JSF page navigation • Running the JSF user interfaces to create and persist entities aUsing JSF with Entity Relationships Setting the environment We need to install Oracle Fusion Middleware 11g (http://www.oracle.com/ technology/software/products/middleware/index.html), which includes WebLogic Server 11g and JDeveloper 11g. Also install Oracle database 10g XE Edition (http://www.oracle.com/technology/software/products/database/ xe/index.html) including the sample schemas. In this chapter, we won't be using the standalone WebLogic Server, but shall test the application in the WebLogic server that is integrated in JDeveloper 11g. However, an EAR file may be created and deployed to the standalone version using a build script, which is discussed in some of the other chapters. If the application is deployed to the standalone version, a data source is required to be configured in WebLogic Server with Oracle database, which is also explained in some of the other chapters, such as Chapter 8, EJB 3.0 Database Persistence with Ajax in the UI. Creating database tables We shall be creating EJB 3.0 entity beans from database tables. Therefore, first we need to create the database table Oracle databaseXE. Connect to the Oracle database XE with theOE schema and create tablesARTICLE,SECTION, andEDITION using the following SQL scripts: CREATE TABLE EDITION (id VARCHAR(100) PRIMARY KEY NOT NULL, journal VARCHAR(100), publisher VARCHAR(100), edition VARCHAR(100)); CREATE TABLE SECTION (id VARCHAR(100) PRIMARY KEY NOT NULL, section VARCHAR(100)); CREATE TABLE ARTICLE (id VARCHAR(100) PRIMARY KEY NOT NULL, title VARCHAR(100), author VARCHAR(100)); We shall be modifying two of these tables later when we map EJB 3.0 relationships between entities. We shall add anEDITION_ID column to theSECTION table, because theEdition entity has one-to-many mapping with theSection entity. And, we shall add theSECTION_ID andEDITION_ID columns to theARTICLE table, asSection and Edition entities have one-to-many mappings with theArticle entity. Creating an EJB 3.0 application In this section, we create an EJB 3.0 application in JDeveloper 11g. Start JDeveloper 11g and select the New Application link in the Application navigator. In the Create Java EE Web Application window, specify an Application Name, EJB3RelationshipsJSF for example, select the Java EE Web Application template, and click on Next. 314 aChapter 9 First, the view controller project is defined. In Name you project, select the default Project Name ViewController, and select the default project Directory. In the Project Technologies tab, shift the EJB technology from the Available column to the Selected column. Click on Next. Next, configure the Java Settings for the view controller project. Select the default Package Name view, in which the JSF backing bean classes get generated when we add JSFs. Select the default Java Source Path and Output Directory and click on Next. Select the default EJB 3.0 settings for the view project. The EJBs are created in the model project, but we shall be invoking the EJBs from the view controller project. Next, configure the Model project. Specify a Project Name (Model by default) and shift the EJB project technology from the Available to the Selected column in the Project Technologies tab. Click on Next. Select the default Java settings for the model project and click on Next. In the Configure EJB Settings window, select the default EJB Version, which is EJB 3.0. EJB 3.0 specification is based on annotations; therefore, Using annotations is selected by default. Click on Next. A Java EE Web Application gets created; the application consists of two projects, the ViewController project and the Model project. We shall create entity and session beans in the Model project and the JSF UIs in the ViewController project. We shall add a dependency in the ViewController project on the Model project to run the JSF UIs in the WebLogic Server that is integrated with JDeveloper 11g: 315 aUsing JSF with Entity Relationships Creating a database connection To generate entity beans from the database tables we created earlier, we need to create a database connection to Oracle database XE. As we are running the application in the integrated WebLogic Server, we shall also be using the connection for database persistence. Select the Database Navigator, right-click on the EJB3RelationshipsJSF application node, and select New Connection. In the Create Database Connection window, specify a Connection Name (OracleDBConnection) and select Connection Type as Oracle (JDBC). Specify Username as OE, as we created the database tables in the OE schema. Specify the Password for the OE schema. Select Driver type as thin, specify Hostname as localhost, and SID as XE. JDBC Port is 1521 by default. Click on OK: A database connection gets created and added to the Database Navigator. The Tables node displays the tables that we created: 316 aChapter 9 Creating entity beans from tables In this section, we create EJB 3.0 entity beans from database tables. Right-click on the Model project node in the Application navigator and select New. In the New Gallery window, select Business TierEJB in Categories and Entities from Tables in Items. Click on OK. Next, we den fi e the Persistence Unit for the entity beans. A Persistence Unit defines a data source, and other database persistence properties for creating and persisting entity beans. A persistence unit is defined in the META- INF/persistence.xml configuration file. Click on New. In the New Persistence Unit window, specify a persistence unit Name (em for example). Specify a JTA Datasource Name. Earlier we created a connection OracleDBConnection. A data source with JNDI namejdbc/OracleDBConnectionDS gets created by default when the connection is created. The data source name is of the formatjdbc/ ConnectionNameDS, in whichConnectionName is the variable; the connection name is what changes based on the database connection defined in JDeveloper. Specify jdbc/OracleDBConnectionDS as the JTA Datasource Name. The TopLink/ EclipseLink is used as the JPA persistence provider. Select the Default Database Platform and the Server Platform as WebLogic 10. Click on OK. A new Persistence Unit (em) gets defined. Click on Next. In the Type of Connection window, a developer may select from an Online Database Connection, an Offline Database Connection, or a Application Server Database Connection. Select Online Database Connection and click on Next. 317 aUsing JSF with Entity Relationships In the Database Connection Details, select the OracleDBConnection that we created earlier. Or, a new connection may be created. Click on Next. In Select Tables, select the OE schema, select the Auto-Query checkbox, and shift the ARTICLE, SECTION, and EDITION tables from the Available column to the Selected column. Click on Next: In the General Options window, specify the Package Name in which the entity beans are to be generated. The default package name is model. Select the default Entity Class Options and click on Next. Next, specify the Entity details: The Table Name from which an entity is to be generated, the Entity name, and the Entity Class. Click on Next. Mapping one database table maps all the other selected database tables similarly. The Summary page lists the entities that will be generated. Click on Finish. The entity classesmodel.Article.java,model.Section.java, andmodel. Edition.java get created: 318 aChapter 9 The default entities generated from the tables do not contain the complete code for the entities. We need to add named queries for finding entities by ID and finding all entities. Edition entity First, we modify themodel.Edition.java entity. Add named queries to find all Edition entities and find an Edition entity by ID: NamedQueries( NamedQuery(name = "findEditionsAll", query = "select o from Edition o"), NamedQuery(name = "findEditionById", query = "SELECT o from Edition o WHERE o.id = :id") ) TheEdition entity implements theSerializable interface. An entity bean that is persisted by an entity manager uses caches to serialize the entity bean. Add astatic final variable to associate the entity versions with a version number: static final long serialVersionUID = 1; As theEdition entity bean has a one-to-many relationship with theSection and Article entities, add parameterized variables of typeList for theSection and Article entities: private ListSection sections; private ListArticle articles; 319 aUsing JSF with Entity Relationships Define a OneToMany relationship to theSection entity. Set thecascade element toCascadeType.ALL to cascade all operations to the target of the association. The mappedBy element species fi the field that owns the relationship. In a one-to-many relationship the many-side must be the owning side of the relationship, which in the example is theEdition entity. Thefetch element species the fetch fi strategy. The default strategy isLAZY, which does not fetch the associated entities when an entity is retrieved.LAZY fetching is useful if an entity has a number of associations, which further have associations and all that is required is a particular entity. But, as we require the associated entities too, set fetch strategy toEAGER, which fetches all the associated entities. Specify a join table for the one-to-many mapping using the JoinTable annotation. Thename element of theJoinTable specifies the table name. Thename element is optional and defaults to the concatenated names of the two associated primary entity tables ThejoinColumns element specifies the foreign key columns of the join table that are mapped to the primary table of the owning entity, and theinverseJoinColumns element specifies the foreign key columns of the join table that reference the table for the non-owning entity. ThejoinColumns and inverseJoinColumns are also optional and default values are used if not specified. The one-to-many mapping for the edition-section relationship is as follows: OneToMany(cascade = CascadeType.ALL, mappedBy = "edition",fetch = FetchType.EAGER) JoinTable(name = "Edition_Section", joinColumns = JoinColumn(name = "edition_section_id", referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "section_id", referencedColumnName ="id") ) Specify the getter/setter methods for theSection entity: public ListSection getSections() return sections; public void setSections(ListSection sections) this.sections = sections; Also add methods to add and remove aSection entity: public void addSection(Section section) this.getSections().add(section); section.setEdition(this); public void removeSection(Section section) this.getSections().remove(section); 320 aChapter 9 Specify the identifier property for the Edition entity. TheGeneratedValue annotation is not required if the ID value is set in the application and not generated automatically: Id GeneratedValue public String getId() return id; Similarly add aOneToMany mapping to theArticle entity. TheEdition entity class is listed as follows: package model; import java.io.Serializable; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; Entity NamedQueries( NamedQuery(name = "findEditionsAll", query = "select o from Edition o"), NamedQuery(name = "findEditionById", query = "SELECT o from Edition o WHERE o.id = :id") ) public class Edition implements Serializable static final long serialVersionUID = 1; private ListSection sections; private ListArticle articles; Column(length = 100) private String edition; Id Column(nullable = false, length = 100) private String id; Column(length = 100) private String journal; Column(length = 100) private String publisher; 321 aUsing JSF with Entity Relationships public Edition() public Edition(String edition, String id, String journal, String publisher) this.edition = edition; this.id = id; this.journal = journal; this.publisher = publisher; public String getEdition() return edition; public void setEdition(String edition) this.edition = edition; Id GeneratedValue public String getId() return id; public void setId(String id) this.id = id; public String getJournal() return journal; public void setJournal(String journal) this.journal = journal; public String getPublisher() return publisher; public void setPublisher(String publisher) this.publisher = publisher; OneToMany(cascade = CascadeType.ALL, mappedBy = "edition", fetch = FetchType.EAGER) JoinTable(name = "Edition_Section", joinColumns = JoinColumn(name = "edition_section_id", 322 aChapter 9 referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "section_id", referencedColumnName = "id") ) public ListSection getSections() return sections; public void setSections(ListSection sections) this.sections = sections; public void addSection(Section section) this.getSections().add(section); section.setEdition(this); public void removeSection(Section section) this.getSections().remove(section); OneToMany(cascade = CascadeType.ALL, mappedBy = "edition", fetch = FetchType.EAGER) JoinTable(name = "Edition_Article", joinColumns = JoinColumn(name = "edition_id", referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "article_id", referencedColumnName = "id") ) public ListArticle getArticles() return articles; public void setArticles(ListArticle articles) this.articles = articles; public void addArticle(Article article) this.getArticles().add(article); article.setEdition(this); public void removeArticle(Article article) this.getArticles().remove(article); The property relates to the name of the table (entity) you query; the join takes the property returned by the getter method as the table name for the join at runtime. 323 aUsing JSF with Entity Relationships Section entity Similarly, to theSection entity add named queries to n fi d all Section entities and n fi d a Section entity by ID. As theSection entity has a one-to-many mapping with theArticle entity den fi e a parameterized variable of type List for theArticle entity. Specify aManyToOne relationship with theEdition entity. If we want to initiate merge, persist, refresh operations from theSection entity, we need to add a join table on theSection entity side. But, if we don't want the associatedEdition to be deleted, then if theSection entity is deleted don't set thecascade element to CascadeType.ALL. Set the fetch strategy toEAGER as we want to retrieve associated entities when an entity is retrieved. ThemappedBy element is not required to be set in a unidirectional relationship; themappedBy element is set on the non-owning side of the relationship, which in the edition-section relationship is theEdition entity. However, if you want to make theSection entity as the owning side too, add the mappedBy element. TheManyToOne relationship with the getter/setter methods for theEdition entity is defined as follows: ManyToOne(cascade = CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH ,fetch = FetchType.EAGER) JoinTable(name = "Edition_Section", joinColumns = JoinColumn(name = "edition_id", referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "section_id", referencedColumnName ="id")) public Edition getEdition() return edition; public void setEdition(Edition edition) this.edition = edition; We also need to add aOneToMany relationship to theArticle entity. Set the cascade element toCascadeType.ALL as we want to cascade all operations to the Article entity. AnArticle entity without aSection entity wouldn't have much significance. Set the mappedBy element toSection as theSection entity is the non- owning side in the relationship. Add getter/setter methods for theArticle entity and also add add/remove methods to add and remove anArticle entity: OneToMany(cascade = CascadeType.ALL, mappedBy = "section", fetch = FetchType.EAGER) JoinTable(name = "Section_Article", joinColumns = JoinColumn(name = "section_id", referencedColumnName = "id") , inverseJoinColumns = 324 aChapter 9 JoinColumn(name = "article_id", referencedColumnName ="id") ) public ListArticle getArticles() return articles; public void setArticles(ListArticle articles) this.articles = articles; public void addArticle(Article article) this.getArticles().add(article); article.setSection(this); public void removeArticle(Article article) this.getArticles().remove(article); TheSection entity is listed as follows: package model; import java.io.Serializable; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; Entity NamedQueries( NamedQuery(name = "findSectionsAll", query = "select o from Section o"), NamedQuery(name = "findSectionById", query = "SELECT o from Section o WHERE o.id = :id") ) public class Section implements Serializable static final long serialVersionUID = 1; private Edition edition; 325 aUsing JSF with Entity Relationships private ListArticle articles; Id Column(nullable = false, length = 100) private String id; Column(length = 100) private String section; public Section() public Section(String id, String section) this.id = id; this.section = section; Id GeneratedValue public String getId() return id; public void setId(String id) this.id = id; public String getSection() return section; public void setSection(String section) this.section = section; ManyToOne(cascade = CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH , fetch = FetchType.EAGER) JoinTable(name = "Edition_Section", joinColumns = JoinColumn(name = "edition_id", referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "section_id", referencedColumnName = "id") ) public Edition getEdition() return edition; public void setEdition(Edition edition) 326 aChapter 9 this.edition = edition; OneToMany(cascade = CascadeType.ALL, mappedBy = "section", fetch = FetchType.EAGER) JoinTable(name = "Section_Article", joinColumns = JoinColumn(name = "section_id", referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "article_id", referencedColumnName = "id") ) public ListArticle getArticles() return articles; public void setArticles(ListArticle articles) this.articles = articles; public void addArticle(Article article) this.getArticles().add(article); article.setSection(this); public void removeArticle(Article article) this.getArticles().remove(article); Article entity Similarly, in theArticle entity, add named queries to find all Article entities and find an Article entity by ID. AddManyToOne annotations to define the many-to- one relationships between theArticle entity and theEdition andSection entities. TheArticle entity is listed as follows: package model; import java.io.Serializable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; 327 aUsing JSF with Entity Relationships import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; Entity NamedQueries( NamedQuery(name = "findArticlesAll", query = "select o from Article o"), NamedQuery(name = "findArticleById", query = "SELECT o from Article o WHERE o.id = :id") ) public class Article implements Serializable static final long serialVersionUID = 1; private Section section; private Edition edition; Column(length = 100) private String author; Id Column(nullable = false, length = 100) private String id; Column(length = 100) private String title; public Article() public Article(String author, String id, String title) this.author = author; this.id = id; this.title = title; public String getAuthor() return author; public void setAuthor(String author) this.author = author; Id GeneratedValue public String getId() return id; 328 aChapter 9 public void setId(String id) this.id = id; public String getTitle() return title; public void setTitle(String title) this.title = title; ManyToOne(cascade = CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH , fetch = FetchType.EAGER) JoinTable(name = "Section_Article", joinColumns = JoinColumn(name = "section_id", referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "article_id", referencedColumnName = "id") ) public Section getSection() return section; public void setSection(Section section) this.section = section; ManyToOne(cascade = CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH , fetch = FetchType.EAGER) JoinTable(name = "Edition_Article", joinColumns = JoinColumn(name = "edition_id", referencedColumnName = "id") , inverseJoinColumns = JoinColumn(name = "article_id", referencedColumnName = "id") ) public Edition getEdition() return edition; public void setEdition(Edition edition) this.edition = edition; You may build the queries using the TopLink/Eclipse Link editing facilities, which you can access from thepersistence.xml file. 329 aUsing JSF with Entity Relationships Entity Persistence Configuration file Thepersistence.xml file is the EJB 3.0 database persistence configuration file and gets generated when entities are created from database tables. But, the persistence.xml file as generated is not complete. The JTA data source JNDI name is specified and the entity classes are also specified. EclipseLink is used as the JPA persistence provider. Thejavax.persistence.jtaDataSource property is pre-specified and set to the JTA data source name. Add the following properties to persistence.xml: Property Value Description eclipselink.target- WebLogic_10 Specifies the target server as server WebLogic Server 10. eclipselink.target- Oracle Specifies the target database. database eclipselink.ddl- create-tables Specifies the DDL generation generation strategy to create tables, but not to delete tables and re-create them. Thepersistence.xml configuration file is listed as follows: ?xml version="1.0" encoding="Cp1252" ? 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" xmlns="http://java.sun.com/xml/ns/persistence" version="1.0" persistence-unit name="em" providerorg.eclipse.persistence.jpa.PersistenceProvider/provider jta-data-source java:/app/jdbc/jdbc/OracleDBConnectionDS /jta-data-source classmodel.Article/class classmodel.Edition/class classmodel.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="javax.persistence.jtaDataSource" value="java:/app/jdbc/jdbc/OracleDBConnectionDS" / /properties /persistence-unit /persistence 330 aChapter 9 /properties /persistence-unit /persistence Creating a session bean In this section, we create aStateless session bean façade for the entity beans. Select the Model project node in Application navigator and select File New. In the New Gallery window, select Business Tier EJB and Session Bean in Items. Click on OK. In the Create Session Bean window, specify the session bean EJB Name, and select Session Type as Stateless and Transaction Type as Container. Specify a Mapped Name, which will be used to lookup the session bean from a client. Select a Persistence Unit and click on Next. Select the default session façade methods to generate and click on Next. Specify the Bean Class and click on Next. Specify the EJB interfaces to implement. Implement only one of the interfaces—local or remote. Select the Implement a Remote Interface checkbox, specify an interface name, and click on Next. In the Summary page, click on Finish. A session bean and a remote interface get created. 331 aUsing JSF with Entity Relationships Session bean class A stateless session bean is just a Java class annotated with the annotation Stateless. Stateless(name = "EJB3SessionEJB", mappedName = "EJB3RelationshipsJSF-Model-EJB3SessionEJB") ThemappedName element specifies the mapped name for the session bean. The mappedName is used in the JNDI lookup of the session bean from a client. The Remote annotation indicates that the class implements a remote interface: Remote public class EJB3SessionEJBBean implements EJB3SessionEJB .. We shall be using anEntityManager for database persistence. Inject an EntityManager using dependency injection: PersistenceContext(unitName = "em") private EntityManager em; AddgetAll methods to retrieve allEdition entities, allSection entities, and allArticle entities. By default, container-managed transactions do not require individual methods to be associated with transactions. Methods may be associated with transactions using the transaction attributes. Associate each of thegetAll methods with a transaction attribute withTransactionAttributeType set to REQUIRES_NEW, which implies that a new transaction is required each time the method is invoked: TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) In each of thegetAll methods, find all entities using the named query to find all entities. ThegetAll methods return a parameterizedList. For example, the getAllEdtions method returnsListEdition. In thegetAllEditions method, create anArrayListEdition type variable: ArrayListEdition editions = new ArrayListEdition(); Create aQuery object for the named queryfindEditionsAll, which was defined in theEdition entity class. AQuery object is created using thecreateNamedQuery method of theEntityManager object that was created using dependency injection: Query q = em.createNamedQuery("findEditionsAll"); 332 a