|
http://in.geocities.com/rsramsam/bmpdemo.htm |
BMP ENTITY BEAN
by
R.S.RAMASWAMY
( published in DeveloperIQ.....DECEMBER-2003)
----------------------------------------------
( IN CONTINUATION OF CMP ENTITY BEANS).
ENTITY BEAN WITH BEAN-MANAGED
PERSISTENCE
==========================================
Thus far, we acquainted ourselves with Sessionbeans
( both stateless & stateful) and also CMP Entity bean.
In this instalment, we take up the most
difficult type, (ie) Bean-Managed Persistent Entity bean.(BMP)
------------------------------------------------------------------
Example for Bean-Managed Entity Bean
====================================
We have to write the SQL code for Persistence ,ourselves, in the case of
Bean-Managed persistence. In our example,If we consider a single instance of
the bean, it exists as an object in memory with 3 attributes
(key,name,place) At the same time, it
should also be persisted as a row, with corresponding fields,
in 'table1' of 'customer'
database in hard disk.They should match. This is known as 'Synchronization'.
The mechanism by which Synchronization is achieved by various vendors
may vary. It is known as 'Object-relational mapping'.
Whether, it is CMP or BMP, the
process of synchronising is done by the container.The only difference is
that , in CMP , we do not write any SQL for Storing ( memory to hard disk)or
for 'Loading' (hard disk to memory).In BMP, we have to write the SQL for
these tasks.
However, the client cannot explicitly , call either 'load' or 'store'
functions. This job is taken care of by the Container.Depending on a number of
factors such as Transaction
monitoring, the container chooses the appropriate moment to synchronize the
data in memory with the data in table of hard disk storage.
This process, is transparent ,(ie) the programmer need not know
about it. The methods are 'callback' methods. Such methods are called by
the container by itself without explicit user program or interaction.
----------------------------------------------------------------
In
CMP, we just deal with the objects in memory. The task of persistence is
automatically done by the container, at the appropriate time. The container
itself generates the required SQL code to perform this task. But, in BMP , we
should write the necessary SQL code for Store and Load.
This is the difference between CMP and BMP.
-----
Which is better? Opinions differ.One camp claims that CMP is better
because,it abstracts the details about the underlying database and deals only
with objects in memory.
The other camp feels that CMP is useful only for very simple cases and
most of the real life applications are complex, requiring joins from different
tables and CMP is not suitable for real life situations.
It
will be safer for us to be conversant with BMP , in case it is needed by our
application.
------
As
before ( as in the case of CMP), we begin with :
i) customerRemote.java
ii) customerHome.java
A
DEMO FOR BEAN-MANAGED PERSISTENT ENTITY-BEAN
================================================
Access Database name : Customer
table name :
table1
Three fields ( key, name, place) ( all String type).
(Primary key field is 'key').
For our example, remember to register the database 'customer'
with ODBC.
---------------------------------------------------
( The java source files for
'customerRemote' &
'customerHome' are the same as
for CMP bean.
====================================================
Let us create our source files in the
following folder:
c:\weblogic\beans\bmpdemo
--------------------------
As before remember to set JAVA_HOME,
WL_HOME.
Also, set path & classpath;
c:\weblogic\beans\bmpdemo>set
JAVA_HOME=C:\JDK1.3
...bmpdemo>set
WL_HOME=C:\WEBLOGIC
...bmpdemo>set
path=c:\windows\command;
c:\jdk1.3\bin;
c:\weblogic\bin
...bmpdemo>set
classpath=c:\weblogic\beans\bmpdemo;
c:\weblogic\classes;
c:\weblogic\lib\weblogicaux.jar;
------------------
customerRemote.java
====================
import javax.ejb.*;
import java.rmi.*;
public interface customerRemote
extends EJBObject
{
public String getName() throws RemoteException;
public void setName(String s)
throws RemoteException;
public String getPlace() throws RemoteException;
public void setPlace(String s) throws RemoteException;
}
================================================================
customerHome.java
=================
import javax.ejb.*;
import java.rmi.*;
public interface customerHome
extends EJBHome
{
public customerRemote create(String a, String b, String c)
throws
RemoteException,
CreateException;
public customerRemote findByPrimaryKey(String a) throws
RemoteException,
FinderException;
}
===================================================================
The difference between CMP and BMP occurs only in the Bean class.
Therefore the Remote and Home files are
exactly same for CMP and BMP.
--------- ----------------------------------------------------------
We now take up customerBean.java
As this is a lenthy file, it is always good
practice to list the sequence in which the functions appear in code file:
(This is just for convenience in code-reading).
1)
setName(
2) getName()
3) setPlace(
4) getPlace()
5) getConnection () ( this is defined by us)
6)
ejbCreate(
7) ejbFindByPrimaryKey(
8) ejbLoad()
9) ejbStore()
10) ejbRemove()
11) ejbPostCreate(
12) ejbSetEntityContext(
13)
ejbUnsetEntityContext()
14) ejbActivate()
15) ejbPassivate()
(note:
A single round bracket means there are parameter/parameters).
----------------------------------------------------------------
It will necessary to give very brief note
on the purpose of these various methods.
a)The important function is 'getConnection'.
This is written by us.
The purpose is to to get
connection to the database.
b) 'ejbCreate' method is called when
the client invokes 'create'
method. Its purpose is to create a
new object in memory with the
parameters passed by the client and also create the corresponding
row in the database table.
c) 'ejbPostCreate'
is called after 'ejbCreate' by the container.This
can be used for any desired tasks.It should have the same
parameters as the 'ejbCreate' method.
d) 'ejbLoad'
is meant for bringing a row from table into the memory.
depending on the primary key in the current context.
( context.getPrimaryKey() ).and setting the attributes of the
object accordingly. This is a 'callback' method (ie) it is invoked
at the appropriate time by the container.
e) 'ejbStore'
is meant for storing the state of the bean specified by
the primary key in the current context and updating the row in
the table accordingly.This also
is a callback method.
f)
'ejbActivate' is a callback method which brings a bean into the
bean-pool.
g) 'ejbPassivate' is a callback method which
removes a bean from
the bean-pool.
Note:
In most of the books, we will find that the authors use
'stored procedure' method using
'PreparedStatement'.
It is not absolutely essential. We have used the much simple
'Statement'
method, so that it will be easier to follow.
Some authors opine that the use of Stored procedure does not
result in any marked improvement in
performance, in network environment!
-------------------------------------------------------------------
// customerBean.java
import javax.ejb.*;
import java.rmi.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
public class customerBean implements
EntityBean
{
public String key;
public String name;
public String place;
public EntityContext context;
Connection
connection;
//------------------------------------------------------------
public String getName()
{
return name;
}
public void setName(String
b)
{
name=b;
}
//----------------------------------------------------------
public String getPlace()
{
return place;
}
public void setPlace(String
c)
{
place=c;
}
//----------------------------------------------------------------
private Connection getconnection() // this is our own method!
{
try
{
Context context= new InitialContext ();
String dsn
= "java:comp/env/jdbc/customer";
DataSource
ds=(DataSource)context.lookup(dsn);
connection =
ds.getConnection();
System.out.println("Connection obtained");
} catch(Exception e1) {
System.out.println(""+e1);}
return
connection;
}
//------------------------------------------------------------
public String ejbCreate(String a, String b, String
c)
throws
CreateException
{
try
{
key = a;
name= b;
place = c;
connection=getconnection();
Statement statement = connection.createStatement();
String sql = "insert into table1
values('"+a+"','"+b+"','"+c+"')";
statement.execute(sql);
connection.close();
System.out.println("Connection closed");
} catch(Exception e1)
{System.out.println(""+e1);}
return key;
}
//-----------------------------------------------------------
public String ejbFindByPrimaryKey (String a)
{
try
{
connection=getconnection();
Statement
statement=connection.createStatement();
String sql=" select * from
table1 where key='"+a+"' ";
ResultSet
rs=statement.executeQuery(sql);
connection.close();
System.out.println("Connection closed");
} catch(Exception e1) {System.out.println(""+e1);}
return a;
}
//-----------------------------------------------------------
public void ejbLoad() // get
the data from database
{
try
{
String pk = (String) context.getPrimaryKey();
// * important
connection =
getconnection();
Statement statement =
connection.createStatement();
String sql = "select * from
table1 where key='"+pk+"' ";
ResultSet
rs=statement.executeQuery(sql);
while(rs.next())
{
key=rs.getString(1);
name=rs.getString(2);
place=rs.getString(3);
}
rs.close();
connection.close();
System.out.println("Connection closed");
} catch(Exception e1) {
System.out.println(""+e1); }
}
//--------------------------------------------------------------------
public void ejbStore() // send
data to database
{
try
{
connection=getconnection();
Statement statement=connection.createStatement();
String pk =
(String) context.getPrimaryKey();
String b =
name;
String c =
place;
String sql=
"update table1 set
name='"+b+"',place='"+c+"' where
key='"+pk+"'";
statement.execute(sql);
connection.close();
System.out.println("Connection closed");
} catch(Exception
e1){System.out.println(""+e1);
}
}
//---------------------------------------------------------------
public void ejbRemove()
{
try
{
connection = getconnection();
Statement statement = connection.createStatement();
String pk = (String) context.getPrimaryKey();
String sql = "delete from table1 where
key='"+pk+"'";
statement.execute(sql);
connection.close();
System.out.println("Connection closed");
}catch(Exception e1){System.out.println(""+e1);}
}
//----------------------------------------------------------------
public void ejbPostCreate(String a,String b,String c)
throws
CreateException
{
System.out.println("post create done");
}
//----------------------------------------------------------------------
public void setEntityContext(EntityContext ec)
{
this.context=ec;
}
//-----------------------------------------
public void unsetEntityContext()
{
try
{
this.context=null;
System.out.println("context unset");
}catch(Exception e1){System.out.println(""+e1);}
}
//--------------------------------------------------------
public void ejbActivate()
{
System.out.println("activated"); // diagnostic
}
//---------------------------------------------------------
public void ejbPassivate()
{
System.out.println("passivated");
// diagnostic
}