If you are used to writing webapps based on JSP and Servlets, you know how tedious it can be to use JDBC whenever you need to update your database with new information. By creating EJB components with container managed persistence, you let Resin-CMP generate the tedious SQL to load, store, and cache entity beans from the database.
Overview
Each CMP bean needs at least three classes:
and one XML file,
The bean also needs a database table that it can use to permanently store
its fields. Each entity will be stored in a row of this
table. (One field must be designated as the primary key). The name of the table
is specified in the deployment descriptor by the <abstract-schema-name> tag.
Our CourseBean will use the following schema:
CREATE TABLE basic_courses (
course_id VARCHAR(250) NOT NULL,
instructor VARCHAR(250),
PRIMARY KEY(course_id)
);
# manually create two sample entities
INSERT INTO basic_courses VALUES('Potions', 'Severus Snape');
INSERT INTO basic_courses VALUES('Transfiguration', 'Minerva McGonagall');
The Deployment Descriptor
The deployment Descriptor for the Course Bean looks like this:
 <ejb-jar>
  <enterprise-beans>
   <entity>
    <ejb-name>basic_CourseBean</ejb-name>
    <local-home>example.cmp.basic.CourseHome</local-home>
    <local>example.cmp.basic.Course</local>
    <ejb-class>example.cmp.basic.CourseBean</ejb-class>
    <persistence-type>Container</persistence-type>
    <reentrant>True</reentrant>
    <prim-key-class>java.lang.String</prim-key-class>
    <primkey-field>courseId</primkey-field>
    <abstract-schema-name>basic_courses</abstract-schema-name>
    <cmp-field>
     <field-name>instructor</field-name>
    </cmp-field>
    <cmp-field>
     <field-name>courseId</field-name>
    </cmp-field>
   </entity>
  </enterprise-beans>
 </ejb-jar>
<ejb-name> denotes the name that this bean is to be referenced by. Resin-CMP also uses this name as the Bean's JNDI name (see below).
The database schema is defined in the deployment descriptor (cmp-basic.ejb) with
<cmp-field> tags. Each <cmp-field> specifies the name of a
field that is to be kept persistant by the container. For example, in this
example there is a <cmp-field> 'instructor'. Therefore, we need an instructor
field in our table, and in the implementation class we need to define two
related methods:
These will be implemented by the container, which fills in the actual JDBC
code.
public abstract String getInstructor();
public abstract void setInstructor(String val);
Using the CMP Bean
Before you can use the CMP bean, it needs to be deployed. Resin-CMP looks for *.ejb deployment descriptors in an application's WEB-INF directory. If a found deployment descriptor is valid, Resin-CMP will automatically deploy all beans that it references. This includes the automatic implementation and compilation of the Home and Local interfaces.
Once the CMP Bean is deployed, we use the home interface to obtain references
to entities that are already stored in the database. First, we use JNDI to
find the Home Interface. The deployment descriptor defines where the Home
Interface is mapped into JNDI:
Context ejb = (Context) new InitialContext().lookup("java:comp/env/cmp");
home = (CourseHome) ejb.lookup("basic_CourseBean");
The Home Interface must always declare the method
findByPrimaryKey(...) that will return the entity associated with a
particular primary key. You declare this method abstract and let Resin-CMP
implement it for you. Its return type needs to be that of the local interface -
in our case, Course
.
Since we have initialized the database
with two sample records, we know that there is an entity with the
primary key "Potions". We can use the findPrimaryKey(...) method to obtain
a reference to the associated entity:
try {
Course course = home.findByPrimaryKey("Potions");
}
catch (FinderException e) {
throw new ServletException(e);
}
From here on the application developer starts to really benefit from
CMP. If we were to change the instructor for the Potions course, we could
call:
This call will automatically update the database to reflect the change in
the instructor field. Resin-CMP has generated all neccessary SQL.
course.setInstructor("Scott");