BMP
1. Create the home interfaces for the bean
The remote home interface defines the create method that a client can invoke remotely to instantiate your bean. The local home interface defines the createmethod that a collocated bean can invoke locally to instantiate your bean.
a. To create the remote home interface, extend javax.ejb.EJBHome .
b. To create the local home interface, extend javax.ejb.EJBLocalHome .
2. Create the component interfaces for the bean.
The remote component interface declares the business methods that a client can invoke remotely. The local interface declares the business methods that a collocated bean can invoke locally.
a. To create the remote component interface, extend javax.ejb.EJBObject .
b. To create the local component interface, extend javax.ejb.EJBLocalObject .
3. Define the primary key for the bean.
The primary key identifies each entity bean instance and is a serializable class. You can use a simple data type class, such as java.lang.String, or define a complex class, such as one with two or more objects as components of the primary key.
4. Implement the entity bean with bean-managed persistence:
a. Provide a complete implementation of the get and set methods that correspond to the get and set method(s) declared in the home interfaces.
For an entity bean with bean-managed persistence, the getter and setter methods are public, because you are responsible for their implementation.
b. Implement the business methods that you declared in the home and component interfaces (if any). The signature for each of these methods must match the signature in the remote or local interface, except that the bean does not throw the RemoteException. Since both the local and the remote interfaces use the bean implementation, the bean implementation cannot throw the RemoteException.
For an entity bean, these methods are often delegated to a session bean
c. Implement any methods that are private to the bean or package used for facilitating the business logic. This includes private methods that your public methods use for completing the tasks requested of them.
d. Implement the ejbCreate methods that correspond to the create method(s) declared in the home interfaces. The container invokes the appropriateejbCreate method when the client invokes the corresponding create method.
The return type of all ebjCreate methods is the type of the bean's primary key.
For an entity bean with bean-managed persistence, provide create methods that allow the client to pass in values that the container will persist to your database. You are responsible for providing an implementation that interacts with your database (usually through straight JDBC calls) to create an instance in the database.
e. Provide a complete implementation for each of the javax.ejb.EntityBean interface container callback methods
For an entity bean with bean-managed persistence, you are responsible for providing an implementation for each these methods that interacts with your database (usually through straight JDBC calls) to manage persistence in the database.
f. Implement a setEntityContext method that takes an instance of EntityContext and unsetEntityContext method
g. Implement the mandatory findByPrimaryKey finder method and, optionally, other
5. Create the appropriate database schema (tables and columns) for the entity bean.
For an entity bean with bean-managed persistence, you are responsible for creating this schema in the database (defined in the data-sources.xml file) before your application attempts to create an instance of your entity bean with bean-managed persistence.
6. Configure your ejb-jar.xml file to match your bean implementation and to reference a data source defined in your data-sources.xml file.
7. Complete the configuration of your entity.
BMP Remote Home Interface
package bmpapp;
import java.rmi.*;
import java.util.*;
import javax.ejb.*;
public interface EmployeeHome extends EJBHome {
public Employee create(Integer empNo, String empName, Float salary)
throws CreateException, RemoteException;
public Employee findByPrimaryKey(EmployeePK pk)
throws FinderException, RemoteException;
public Collection findByName(String empName)
throws FinderException, RemoteException;
public Collection findAll()
throws FinderException, RemoteException;
}
BMP Remote Component Interface
package bmpapp;
import java.rmi.*;
import javax.ejb.*;
public interface Employee extends EJBObject {
// getter remote methods
public Integer getEmpNo() throws RemoteException;
public String getEmpName() throws RemoteException;
public Float getSalary() throws RemoteException;
// setter remote methods
public void setEmpNo(Integer empNo) throws RemoteException;
public void setEmpName(String empName) throws RemoteException;
public void setSalary(Float salary) throws RemoteException;
}
Entity Bean With Bean-Managed Persistence
package bmpapp;
import java.util.*;
import java.rmi.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import javax.ejb.*;
public class EmployeeBean implements EntityBean {
public Integer empNo;
public EntityContext ctx;
private Connection conn = null;
private PreparedStatement ps = null;
private EmployeePK pk;
private static final String dsName = "jdbc/OracleDS";
private static final String insertStatement =
"INSERT INTO EMP (EMPNO, ENAME, SAL) VALUES (?, ?, ?)";
private static final String updateStatement =
"UPDATE EMP SET ENAME=?, SAL=? WHERE EMPNO=?";
private static final String deleteStatement =
"DELETE FROM EMP WHERE EMPNO=?";
private static final String findAllStatement =
"SELECT EMPNO, ENAME, SAL FROM EMP";
private static final String findByPKStatement =
"SELECT EMPNO, ENAME, SAL FROM EMP WHERE EMPNO = ?";
private static final String findByNameStatement =
"SELECT EMPNO, ENAME, SAL FROM EMP WHERE ENAME = ?";
// or you can define a variable specific to orion to implement finder-method:
// or use <finder-method/> in orion-ejb-jar.xml
public static final String findByNameQuery="full: " +
"SELECT EMPNO, ENAME, SAL FROM EMP WHERE ENAME = $1";
public EmployeeBean() {
// Empty constructor, don't initialize here but in the create().
// passivate() may destroy these attributes in the case of pooling
}
public EmployeePK ejbCreate(Integer empNo, String empName, Float salary)
throws CreateException {
try {
pk = new EmployeePK(empNo, empName, salary);
conn = getConnection(dsName);
ps = conn.prepareStatement(insertStatement);
ps.setInt(1, empNo.intValue());
ps.setString(2, empName);
ps.setFloat(3, salary.floatValue());
ps.executeUpdate();
return pk;
}
catch (SQLException e) {
System.out.println("Caught an exception 1 " + e.getMessage() );
throw new CreateException(e.getMessage());
}
catch (NamingException e) {
System.out.println("Caught an exception 1 " + e.getMessage() );
throw new EJBException(e.getMessage());
}
finally {
try {
ps.close();
conn.close();
} catch (SQLException e) {
throw new EJBException(e.getMessage());
}
}
}
public void ejbPostCreate(Integer empNo, String empName, Float salary)
throws CreateException {
}
public EmployeePK ejbFindByPrimaryKey(EmployeePK pk)
throws FinderException {
if (pk == null || pk.empNo == null) {
throw new FinderException("Primary key cannot be null");
}
try {
conn = getConnection(dsName);
ps = conn.prepareStatement(findByPKStatement);
ps.setInt(1, pk.empNo.intValue());
ps.executeQuery();
ResultSet rs = ps.getResultSet();
if (rs.next()) {
pk.empNo = new Integer(rs.getInt(1));
pk.empName = new String(rs.getString(2));
pk.salary = new Float(rs.getFloat(3));
}
else {
throw new FinderException("Failed to select this PK");
}
}
catch (SQLException e) {
throw new FinderException(e.getMessage());
}
catch (NamingException e) {
System.out.println("Caught an exception 1 " + e.getMessage() );
throw new EJBException(e.getMessage());
}
finally {
try {
ps.close();
conn.close();
}
catch (SQLException e) {
throw new EJBException(e.getMessage());
}
}
return pk;
}
public Collection ejbFindAll() throws FinderException {
//System.out.println("EmployeeBean.ejbFindAll(): begin");
Vector recs = new Vector();
try {
conn = getConnection(dsName);
ps = conn.prepareStatement(findAllStatement);
ps.executeQuery();
ResultSet rs = ps.getResultSet();
int i = 0;
while (rs.next()) {
pk = new EmployeePK();
pk.empNo = new Integer(rs.getInt(1));
pk.empName = new String(rs.getString(2));
pk.salary = new Float(rs.getFloat(3));
recs.add(pk);
}
}
catch (SQLException e) {
throw new FinderException(e.getMessage());
}
catch (NamingException e) {
System.out.println("Caught an exception 1 " + e.getMessage() );
throw new EJBException(e.getMessage());
}
finally {
try {
ps.close();
conn.close();
}
catch (SQLException e) {
throw new EJBException(e.getMessage());
}
}
return recs;
}
public Collection ejbFindByName(String empName)
throws FinderException {
//System.out.println("EmployeeBean.ejbFindByName(): begin");
if (empName == null) {
throw new FinderException("Name cannot be null");
}
Vector recs = new Vector();
try {
conn = getConnection(dsName);
ps = conn.prepareStatement(findByNameStatement);
ps.setString(1, empName);
ps.executeQuery();
ResultSet rs = ps.getResultSet();
int i = 0;
while (rs.next()) {
pk = new EmployeePK();
pk.empNo = new Integer(rs.getInt(1));
pk.empName = new String(rs.getString(2));
pk.salary = new Float(rs.getFloat(3));
recs.add(pk);
}
}
catch (SQLException e) {
throw new FinderException(e.getMessage());
}
catch (NamingException e) {
System.out.println("Caught an exception 1 " + e.getMessage() );
throw new EJBException(e.getMessage());
}
finally {
try {
ps.close();
conn.close();
}
catch (SQLException e) {
throw new EJBException(e.getMessage());
}
}
return recs;
}
public void ejbLoad() throws EJBException {
//Container invokes this method to instruct the instance to
//synchronize its state by loading it from the underlying database
//System.out.println("EmployeeBean.ejbLoad(): begin");
try {
pk = (EmployeePK) ctx.getPrimaryKey();
ejbFindByPrimaryKey(pk);
}
catch (FinderException e) {
throw new EJBException (e.getMessage());
}
}
public void ejbStore() throws EJBException {
//Container invokes this method to instruct the instance to
//synchronize its state by storing it to the underlying database
//System.out.println("EmployeeBean.ejbStore(): begin");
try {
pk = (EmployeePK) ctx.getPrimaryKey();
conn = getConnection(dsName);
ps = conn.prepareStatement(updateStatement);
ps.setString(1, pk.empName);
ps.setFloat(2, pk.salary.floatValue());
ps.setInt(3, pk.empNo.intValue());
if (ps.executeUpdate() != 1) {
throw new EJBException("Failed to update record");
}
}
catch (SQLException e) {
throw new EJBException(e.getMessage());
}
catch (NamingException e) {
System.out.println("Caught an exception 1 " + e.getMessage() );
throw new EJBException(e.getMessage());
}
finally {
try {
ps.close();
conn.close();
}
catch (SQLException e) {
throw new EJBException(e.getMessage());
}
}
}
public void ejbRemove() throws RemoveException {
//Container invokes this method befor it removes the EJB object
//that is currently associated with the instance
//System.out.println("EmployeeBean.ejbRemove(): begin");
try {
pk = (EmployeePK) ctx.getPrimaryKey();
conn = getConnection(dsName);
ps = conn.prepareStatement(deleteStatement);
ps.setInt(1, pk.empNo.intValue());
if (ps.executeUpdate() != 1) {
throw new RemoveException("Failed to delete record");
}
}
catch (SQLException e) {
throw new RemoveException(e.getMessage());
}
catch (NamingException e) {
System.out.println("Caught an exception 1 " + e.getMessage() );
throw new EJBException(e.getMessage());
}
finally {
try {
ps.close();
conn.close();
}
catch (SQLException e) {
throw new EJBException(e.getMessage());
}
}
}
public void ejbActivate() {
// Container invokes this method when the instance is taken out
// of the pool of available instances to become associated with
// a specific EJB object
//System.out.println("EmployeeBean.ejbActivate(): begin");
}
public void ejbPassivate() {
// Container invokes this method on an instance before the instance
// becomes disassociated with a specific EJB object
//System.out.println("EmployeeBean.ejbPassivate(): begin");
}
public void setEntityContext(EntityContext ctx) {
//Set the associated entity context
//System.out.println("EmployeeBean.setEntityContext(): begin");
this.ctx = ctx;
}
public void unsetEntityContext() {
//Unset the associated entity context
//System.out.println("EmployeeBean.unsetEntityContext(): begin");
this.ctx = null;
}
/**
* methods inherited from EJBObject
*/
public Integer getEmpNo() {
pk = (EmployeePK) ctx.getPrimaryKey();
return pk.empNo;
}
public String getEmpName() {
pk = (EmployeePK) ctx.getPrimaryKey();
return pk.empName;
}
public Float getSalary() {
pk = (EmployeePK) ctx.getPrimaryKey();
return pk.salary;
}
public void setEmpNo(Integer empNo) {
pk = (EmployeePK) ctx.getPrimaryKey();
pk.empNo = empNo;
}
public void setEmpName(String empName) {
pk = (EmployeePK) ctx.getPrimaryKey();
pk.empName = empName;
}
public void setSalary(Float salary) {
pk = (EmployeePK) ctx.getPrimaryKey();
pk.salary = salary;
}
public EJBHome getEJBHome() {
return ctx.getEJBHome();
}
public Handle getHandle() throws RemoteException {
return ctx.getEJBObject().getHandle();
}
public Object getPrimaryKey() throws RemoteException {
return ctx.getEJBObject().getPrimaryKey();
}
public boolean isIdentical(EJBObject remote) throws RemoteException {
return ctx.getEJBObject().isIdentical(remote);
}
public void remove() throws RemoveException, RemoteException{
ctx.getEJBObject().remove();
}
/**
* Private methods
*/
private Connection getConnection(String dsName)
throws SQLException, NamingException {
DataSource ds = getDataSource(dsName);
return ds.getConnection();
}
private DataSource getDataSource(String dsName) throws NamingException {
DataSource ds = null;
Context ic = new InitialContext();
ds = (DataSource) ic.lookup(dsName);
return ds;
}
}
ejb-jar.xml
<enterprise-beans>
<entity>
<description>no description</description>
<display-name>EmployeeBean</display-name>
<ejb-name>EmployeeBean</ejb-name>
<home>bmpapp.EmployeeHome</home>
<remote>bmpapp.Employee</remote>
<ejb-class>bmpapp.EmployeeBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>bmpapp.EmployeePK</prim-key-class>
<reentrant>False</reentrant>
<resource-ref>
<res-ref-name>jdbc/OracleDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Application</res-auth>
</resource-ref>
</entity>
</enterprise-beans>
Entity Bean With Bean-Managed Persistence Data Source
<connection-pool name="Example Connection Pool">
<!-- This is an example of a connection factory that emulates XA behavior. -->
<connection-factory factory-
user="scott"
password="tiger"
url="jdbc:oracle:thin:@//localhost:1521/oracle.regress.rdbms.dev.us.oracle.com">
</connection-factory>
</connection-pool>
<managed-data-source name="OracleDS"
connection-pool-name="Example Connection Pool"
jndi-name="jdbc/OracleDS"/>