ENTITY BEAN WITHBEAN-MANAGED PERSISTENCE
Thus far, we acquainted ourselves with Sessionbeans ( both stateless & stateful) and also CMP Entity bean.
also read:
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 arow,with correspondingfields,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 CMPor BMP, the process of synchronising is done by the container.The only difference is that , in CMP , we do not write anySQL for Storing ( memory to hard disk) or for 'Loading' (hard disk to memory).In BMP, we have to write the SQLfor thesetasks.
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 factorssuch 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 :
- customerRemote.java
- customerHome.java
A DEMO FOR BEAN-MANAGED PERSISTENT ENTITY-BEAN
Access Database name : Customer tablename: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:weblogicbeansbmpdemo
As before remember to set JAVA_HOME, WL_HOME. Also, set path & classpath;
c:weblogicbeansbmpdemo>set JAVA_HOME=C:JDK1.3 ...bmpdemo>set WL_HOME=C:WEBLOGIC ...bmpdemo>set path=c:windowscommand; c:jdk1.3bin; c:weblogicbin ...bmpdemo>set classpath=c:weblogicbeansbmpdemo; c:weblogicclasses; c:weblogiclibweblogicaux.jar;
customerRemote.java
import javax.ejb.*; import java.rmi.*; public interface customerRemote extends EJBObject { public StringgetName()throws RemoteException; public voidsetName(Strings)throws RemoteException; public StringgetPlace()throws RemoteException; publicvoidsetPlace(String s) throws RemoteException; }
customerHome.java
import javax.ejb.*; import java.rmi.*; public interface customerHome extends EJBHome { publiccustomerRemotecreate(String a, String b, String c) throws RemoteException, CreateException; public customerRemotefind By PrimaryKey(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).
- setName()
- getName()
- setPlace()
- getPlace()
- getConnection ()( this is defined by us)
- ejbCreate(
- ejbFindByPrimaryKey(
- ejbLoad()
- ejbStore()
- ejbRemove()
- ejbPostCreate(
- ejbSetEntityContext(
- ejbUnsetEntityContext()
- ejbActivate()
- 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.
- The important function is 'getConnection'. This is written by us.Thepurpose is to to get connection to the database.
- 'ejbCreate' method is called when the client invokes 'create' method. Its purpose is to create anew object in memory with the parameters passed by the client and also create the corresponding row in the database table.
- '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.
- '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.
- 'ejbStore' is meant for storing the state of the bean specified by the primary key in the current context and updating the row in thetable accordingly.This also is a callback method.
- 'ejbActivate' is a callback method which brings a bean into the bean-pool.
- '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 { publicStringkey; publicStringname; publicStringplace; publicEntityContextcontext; Connectionconnection; //------------------------------------------------------------ public String getName() { returnname; } public void setName(String b) { name=b; } //---------------------------------------------------------- public StringgetPlace() { returnplace; } public void setPlace(String c) { place=c; } //---------------------------------------------------------------- private Connection getconnection()// this is our own method! { try { Contextcontext=new InitialContext(); Stringdsn='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; } //------------------------------------------------------------ publicStringejbCreate(String a, String b, String c) throws CreateException { try { key=a; name=b; place = c; connection=getconnection(); Statementstatement= connection.createStatement(); Stringsql = 'insert into table1 values(''+a+'',''+b+'',''+c+'')'; statement.execute(sql); connection.close(); System.out.println('Connection closed'); } catch(Exceptione1) {System.out.println(''+e1);} returnkey; } //----------------------------------------------------------- publicStringejbFindByPrimaryKey(String a) { try { connection=getconnection(); Statementstatement=connection.createStatement(); Stringsql=' select * from table1 where key=''+a+'' '; ResultSetrs=statement.executeQuery(sql); connection.close(); System.out.println('Connection closed'); } catch(Exception e1) {System.out.println(''+e1);} returna; } //----------------------------------------------------------- publicvoid ejbLoad()//get the data from database { try { Stringpk = (String) context.getPrimaryKey(); // * important connection=getconnection(); Statementstatement=connection.createStatement(); Stringsql = 'select * from table1 where key=''+pk+'' '; ResultSetrs=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); } } //-------------------------------------------------------------------- publicvoidejbStore()//send data to database { try { connection=getconnection(); Statementstatement=connection.createStatement();