Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Entity Bean • An entity bean represents a business object by a persistent database table instead of representing a client. Students, teachers, and courses are some examples of entity beans. • Each entity bean has an underlying table in the database and each instance of the bean is stored in a row of the table. An entity bean does not correspond to any specific client. It provides shared entities for clients. • It is supported by the EJB transaction service via its container. It has a persistent state with a unique primary key identifier which can be used by a client to locate a particular entity bean. Overview (cont.) • Clients look up an existing entity bean by its primary key that is implemented by finding a row in its corresponding data table. • A session bean does not have any primary identifier so that it does not have any findXXX() methods. • Just like a session bean, any entity bean also has two interfaces and one implementation bean class. • There are two types of entity beans: Bean Managed Persistence (BMP) entity beans and Container Managed Persistence (CMP) entity beans. Life Cycle of an Entity Bean • Since BMP and CMP have very similar life cycle we will not discuss the life cycle of CMP and BMP entity bean separately. • BMP developers have full controls over database access but for CMP the EJB container takes care of it. • For example in BMP, the insertion of a row to the table for an new instance of BMP is specified in the ejbCreate() method; the removal of an BMP object is done by deleting a row in its table specified in the ejbRemove() method; the synchronization of BMP with its database table is specified in ejbLoad() and ejbStore()methods; the searching for a entity bean is specified in the ejbFindXXX() methods. In other word, EJB developers must know JDBC very well. • For CMP, EJB developers don’t need to know the detailed JDBC implementations. Life Cycle of an Entity Bean BMP Entity Bean • BMP is a better choice in some applications, JDBC proficient entity bean developers feel more comfortable to take over the responsibility of managing the EJB persistence by themselves in the sense of flexibility or other reasons. • An entity bean with BMP must perform JDBC storing data code to store the bean to its persistent storage and loading data code to load the bean from its persistent storage, and insert and delete operation as well. • The life cycle of a BMP entity bean is introduced in the section of entity bean life cycle. When a business method is called on a BMP bean, the ejbActivate() is called first, followed by ejbLoad() method where the developer must load the persistent data to synchronize the bean with its data table, then the business method is invoked. • The ejbLoad() and ejbStore() methods should be specified by EJB developers to guarantee the synchronization before a bean moves to its inactive stage. Your First BMP Entity Bean • Here is an example of a student BMP entity bean. It stores pairs of student-id and studentGPA. A database table for this bean must be created by the following SQL statement: CREATE TABLE student (id VARCHAR(3) CONSTRAINT pk_student PRIMARY KEY, score Number(1,0) ); Your First BMP Entity Bean (cont.) //The following is the home interface for this student //BMP entity bean. import javax.ejb.*; import java.util.*; public interface StudentHome extends EJBHome { public Student create(String id, double gpa) throws RemoteException, CreateException; public Account findByPrimaryKey(String id) throws FinderException, RemoteException; } Your First BMP Entity Bean (cont.) //The following code is the remote interface for this //student BMP entity bean. import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Student extends EJBObject { public double getScore() throws RemoteException; } //The following is the BMP implementation entity bean //where SQL statements are explicitly included. Your First BMP Entity Bean (cont.) import import import import import java.sql.*; javax.sql.*; java.util.*; javax.ejb.*; javax.naming.*; public class StudentEJB implements EntityBean { private String id; private double score; private EntityContext context; private Connection con; private String dbName = "java:comp/env/jdbc/StudentDB"; public double getScore() { return score; } Your First BMP Entity Bean (cont.) //The following ejb callback methods are executed by EJB //container. When a new bean instance is created the //method ejbCreate() is automatically called by the //container to insert a row in a corresponding table //in the database. public String ejbCreate(String id, double gpa) throws CreateException { try { insertRow(id, score); } catch (Exception ex) { throw new EJBException("ejbCreate: "); } this.id = id; this.score = score; return id; } Your First BMP Entity Bean (cont.) public String ejbFindByPrimaryKey(String primaryKey) throws FinderException { try { Boolean result = selectByPrimaryKey(primaryKey); } catch (Exception ex) { throw new EJBException("ejbFindByPrimaryKey: "); } if (result) { return primaryKey; } else { throw new ObjectNotFoundException ("Row for id " + primaryKey + " not found."); } } Your First BMP Entity Bean (cont.) public void ejbRemove() { try { deleteRow(id); } catch (Exception ex) { throw new EJBException("ejbRemove: "); } } public void setEntityContext(EntityContext context) { this.context = context; try { makeConnection(); } catch (Exception ex) { throw new EJBException( "Failed to connect to database.”); } } Your First BMP Entity Bean (cont.) public void ejbActivate() { id = (String)context.getPrimaryKey(); } public void ejbPassivate() { id = null; } public void ejbLoad() { try { loadRow(); } catch (Exception ex) { throw new EJBException("ejbLoad: "); } } Your First BMP Entity Bean (cont.) public void ejbStore() { try { storeRow(); } catch (Exception ex) { throw new EJBException("ejbLoad: " ); } } public void ejbPostCreate(String id, double score) { } void makeConnection() throws NamingException, SQLException { InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dbName); con = ds.getConnection(); } Your First BMP Entity Bean (cont.) //The following methods are callback methods to invoke //SQL statements to access database void insertRow (String id, double gpa) throws SQLException { String insertStatement = "insert into student values (?,?)"; PreparedStatement prepStmt = con.prepareStatement(insertStatement); prepStmt.setString(1, id); prepStmt.setDouble(2, gpa); prepStmt.executeUpdate(); prepStmt.close(); } Your First BMP Entity Bean (cont.) void deleteRow(String id) throws SQLException { String deleteStatement = "delete from student where id = ? "; PreparedStatement prepStmt = con.prepareStatement(deleteStatement); prepStmt.setString(1, id); prepStmt.executeUpdate(); prepStmt.close(); } boolean selectByPrimaryKey(String primaryKey) throws SQLException { String selectStatement="select id "+ "from student where id = ? "; PreparedStatement prepStmt = con.prepareStatement(selectStatement); prepStmt.setString(1, primaryKey); ResultSet rs = prepStmt.executeQuery(); boolean result = rs.next(); prepStmt.close(); return result; } Your First BMP Entity Bean (cont.) void loadRow() throws SQLException { String selectStatement = "select score " + "from student where id = ? "; PreparedStatement prepStmt = con.prepareStatement(selectStatement); prepStmt.setString(1, this.id); ResultSet rs = prepStmt.executeQuery(); if (rs.next()) { this.score = rs.getDouble(2); prepStmt.close(); } else { prepStmt.close(); throw new NoSuchEntityException(id + " not found."); } } Your First BMP Entity Bean (cont.) void storeRow() throws SQLException { String updateStatement = "update student set score = ? " + "where id = ?"; PreparedStatement prepStmt = con.prepareStatement(updateStatement); prepStmt.setDouble(1, score); prepStmt.setString(2, id); int rowCount = prepStmt.executeUpdate(); prepStmt.close(); if (rowCount == 0) { throw new EJBException("Store id " + id + " failed."); } } CMP Entity Bean • For these entity bean developers without much JDBC experiences, the CMP is a better and easier choice since bean deployers can help to take care of persistence management. Generally, CMP is a prefer choice over BMP due to its high performance, database independence, and easy development and deployment. • An entity bean with CMP relies on the EJB container to perform all database operations which are specified in the deployment descriptor. CMP is simpler than BMP in term of programming coding but CMP requires deployment administrator to do the configuration works. • For the life cycle of CMP, developers don’t need to do anything with ejbLoad() and ejbStore() since the synchronization is taken care of by EJB container itself. Your first CMP Bean • This simple CMP bean application demonstrates a company department and employee management with a department CMP entity bean named dept and an employee CMP entity bean named emp, and a CMR one to many relationship between dept entity bean and emp entity bean. • For any department there may be zero (some department may be just established without any employee) or many employee; for each employee there must be one and only one department this employee works for. This diagram shows the relationship between these two entity beans. The relationship between dept and emp CMP entity beans Your first CMP Bean (cont.) • The LocalDeptHome.java specifies the Local home interface for dept CMP bean. A local interface is intended to be used by a local client at same server. package company; import java.util.*; import javax.ejb.*; public interface LocalDeptHome extends EJBLocalHome { public LocalCustomer create (String deptID, String deptLoc ) throws CreateException; public LocalCustomer findByPrimaryKey (deptID) throws FinderException; } Your first CMP Bean (cont.) • The LocalDept.java specifies the Local object interface for dept CMP bean. A local interface is intended to be used by a local client at same server. package company; import java.util.*; import javax.ejb.*; public interface LocalDept extends EJBLocalObject { public String getDeptID(); public String getDeptLoc(); public Vector getEmp(); public void addEmp (LocalEmp emp); } Your first CMP Bean (cont.) • The DeptBean.java implements two above interface of this dept CMP bean. The getDeptID() and setDeptID(), getDeptLoc()and setDeptLoc() imply that this CMP bean has two CMP property fields: DeptID and DeptLoc. • The getEmp() and addEmp() are used for the CMR relationship field between dept and emp. package company; import java.util.*; import javax.ejb.*; Your first CMP Bean (cont.) public abstract class DeptBean implements EntityBean { private EntityContext context; // cmp fields: pmk and other fields, all abstract public abstract String geDeptID(); public abstract void setDeptID(String id); public abstract String getDeptLoc(); public abstract void setDeptLoc(String loc); //cmr fields: 1:n relationship from dept to emp, //all abstract methods public abstract Collection getEmp(); public abstract void setEmp (Collection emp); Your first CMP Bean (cont.) //business methods public Vector getEmp() { Vector v = new Vector(); Iterator i = getEmp().iterator(); while (i.hasNext()) { v.add((LocalEmp)i.next());} return v; } public void addEmp (LocalEmp emp) { getEmp().add(emp); } Your first CMP Bean (cont.) private String create(String id, String loc) throws CreateException { setDeptID(id); setDeptLoc(loc); return id; } public String ejbCreate (String id, String loc) throws CreateException { return create(id, loc); } public void ejbPostCreate (String id, String loc) throws CreateException { } Your first CMP Bean (cont.) public public public public public public public } void void void void void void void setEntityContext(EntityContext ctx) {} unsetEntityContext() {} ejbRemove() { } ejbLoad() { } ejbStore() { } ejbPassivate() { } ejbActivate() { } Your first CMP Bean (cont.) The LocalEmpHome.java specifies the local home interface for the emp CMP entity bean. package company; import javax.ejb.*; public interface LocalEmpHome extends EJBLocalHome { public LocalEmp create ( String dpetID, String empID, String name, Float salary) throws CreateException; public LocalEmp findByPrimaryKey(String empID) throws FinderException; } Your first CMP Bean (cont.) The LocalEmp.java specifies the local object interface for this emp CMP entity bean. package company; import javax.ejb.*; public interface LocalEmp extends EJBLocalObject{ public String getEmpID(); public String getName(); public float getSalary(); } Your first CMP Bean (cont.) • The EmpBean.java specifies the bean class implementation for this emp CMP entity bean. It indicates that this bean has three CMP property fields: empID, empName and Salary. package company; import java.util.*; import javax.ejb.*; import javax.naming.*; public abstract class EmpBean implements EntityBean { private EntityContext context; //for cmp fields: all abstract access methods public abstract String getEmpID(); public abstract void setEmpID(String id); Your first CMP Bean (cont.) public public public public public abstract String getName(); abstract void setName(String name); abstract float getSalary(); abstract void setSalary(float sal); String ejbCreate(String did, String eid, String name, float sal) throws CreateException { return create (eid, name, sal); } private String create( String id, String name, float sal) throws CreateException { setEmpID(id); setName(name); setSalary(sal); return id; } Your first CMP Bean (cont.) //Other EntityBean callback methods. Notice ejbPostCreate() // must add this new employee by dept.addEmp() to make // sure each employee has one department to work for. public void ejbPostCreate(String did,String eid, String name, float sal) throws CreateException {postCreate(did);} private void postCreate (String did) { try { Context ic = new InitialContext(); LocalCustomerHome home = (LocalDeptHome) ic.lookup("java:comp/env/ejb/DeptRef"); LocalDept dept = home.findByPrimaryKey(did); dept.addEmp((LocalEmp)context.getEJBLocalObject()); Your first CMP Bean (cont.) } catch (Exception ex) { context.setRollbackOnly(); ex.printStackTrace(); } } public void setEntityContext(EntityContext ctx) { context = ctx; } public void unsetEntityContext() { context = null; } public public public public public } void void void void void ejbRemove() { } ejbLoad() { } ejbStore() { } ejbPassivate() { } ejbActivate() { }