Download Entity Bean

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
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() { }