User: mulder
Date: 00/09/16 11:54:35
Modified: manual developing.html index.html warning.html
Log:
Add "writing EJBs" section.
Revision Changes Path
1.2 +304 -0 jbossweb/manual/developing.html
Index: developing.html
===================================================================
RCS file: /products/cvs/ejboss/jbossweb/manual/developing.html,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- developing.html 2000/09/14 18:28:35 1.1
+++ developing.html 2000/09/16 18:54:34 1.2
@@ -5,5 +5,309 @@
</head>
<body>
<h1 ALIGN="CENTER">jBoss 2.0: Writing EJBs</h1>
+ <p>This section is not specific to jBoss. Since EJB is an open
+ specification, the process of writing EJBs is the same across
+ all servers that support the same revision of the spec. If you're
+ familiar with EJBs, this will basically be review, just hitting
+ some of the points that frequently come up on the mailing lists.
+ If you're not familiar with EJBs, this is probably not going to
+ be enough to get you up to speed. At a minimum, you should read
+ the
+ <a
HREF="http://java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/Overview4.html">Section
+ on EJBs</a> in the J2EE
+ <a
HREF="http://java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/DevGuideTOC.html">Developer's
+ Guide</a> on Sun's web site. But we also recommend you pick up
+ a good book or guide, and even check out the
+ <a HREF="http://java.sun.com/products/ejb/docs.html">EJB 1.1
+ Specification</a>.</p>
+
+ <h2><a NAME="ejb11">jBoss 2.0 Supports EJB 1.1</a></h2>
+ <p>The first revision of the EJB spec to be widely implemented was
+ EJB 1.0. However, the current revision is EJB 1.1, and that is
+ what jBoss 2.0 supports. At this time, the EJB 2.0 spec has
+ reached the public draft stage, so it is likely that jBoss 3.x
+ will support the EJB 2.0 specification. If you'd like to review
+ the EJB 1.1 specification it is
+ <a HREF="http://java.sun.com/products/ejb/docs.html">available
+ from Sun</a>, but do yourself a favor and print it double-sided
+ if you can!</p>
+
+ <h2><a NAME="entity">Entity Beans</a></h2>
+ <p>Entity Bean support is required in the EJB 1.1 specification, and
+ jBoss fully supports entity beans. Entity beans can be broken
+ down into two types, depending on the persistance mechanism they
+ use. Container-managed persistance (CMP) beans rely on the server
+ to handle all persistance - saving, loading, looking for specific
+ instances, etc. Bean-managed persistance (BMP) beans handle
+ persistence on their own - you must code it all. jBoss supports
+ both types of entity beans.</p>
+
+ <h3><a NAME="cmp">CMP Entity Beans</a></h3>
+ <p>If you use CMP entity beans, the persistance of you beans is
+ controlled in jBoss by a CMP Persistance Manager. The default
+ CMP Persistance Manager in jBoss is known as JAWS. There are
+ also several third-party persistance managers that you can use
+ with jBoss (see <a HREF="third_party.html">Third-Party
+ Software</a>), but there is no difference until you actually
+ deploy your beans (see <a HREF="deploying.html">Deploying EJBs in
+ jBoss</a>).</p>
+ <p>The common requirements for CMP beans are that all the persistant
+ fields be public and non-static. If you want them to map directly
+ into database types, be sure to use Java types that JDBC is aware
+ of. For example, an <code>int</code> or a
+ <code>java.sql.Date</code> will map directly to database columns,
+ whereas a <code>java.util.Vector</code> or a
+ <code>java.util.Date</code> will be serialized and stored as a
+ byte array. If in doubt, check whether there's a setter in
+ <code>PreparedStatement</code> and a getter in
+ <code>ResultSet</code> that takes your variable type as an
+ argument.</p>
+ <p>If your bean handles data in a complex form (an Object with a
+ number of fields) but you still don't want it to be serialized
+ to the database, you can be a little tricky. You can declare
+ extra variables for the persistant fields that you want to break
+ your Object into, and then use the ejbLoad and ejbStore methods
+ to translate between the Object representation and the primitive
+ field representations. Then when you deploy the bean, you mark
+ your extra variables as CMP fields, and not your Object variable.
+ Here's a quick example:</p>
+<pre>
+public class EMailAddress {
+ public String userName;
+ public String emailAddress;
+}
+
+public class MyBean implements EntityBean {
+ public String dbUserName;
+ public String dbEmail;
+ private EMailAddress address;
+ ...
+ public EMailAddress getAddress() {return address;}
+ public void setAddress(EMailAddress add) {address=add;}
+ ...
+ public void ejbStore() {
+ dbUserName = address.userName;
+ dbEmail = address.emailAddress;
+ }
+ public void ejbLoad() {
+ address = new EMailAddress;
+ address.userName = dbUserName;
+ address.emailAddress = dbEmail;
+ }
+ ...
+}
+</pre>
+ <p>You can also use other Entity Beans as persistant fields. In
+ this manner you can implement parent-child relationships (an
+ order with several line items, for example). JAWS supports
+ this technique, though we recommend that where possible the
+ child entities be available on the same server.</p>
+
+ <h4><a NAME="cmppk">Primary Keys for CMP Beans</a></h4>
+ <p>Every entity bean must have a primary key. The specification is
+ more strict for CMP primary keys than for BMP primary keys.
+ However, you still have two options.</p>
+ <p>If your primary key only consists of one field, you can declare
+ the primary key class to be the type of that field
+ (<code>java.lang.String</code>, or whatever). This is quite
+ simple, but remember to specify which field in your bean is the
+ primary key field when you go to deploy (your bean make have
+ several fields of type <code>String</code>, so you need to
+ declare which one is the primary key).</p>
+ <p>If your primary key has multiple fields, or you want greater
+ compatibility with older EJB server products, you need to create
+ a new class for your primary key. This class must be public,
+ non-abstract, implement <code>java.io.Serializable</code>, and
+ have fields that correspond to the bean's primary key fields.
+ Each of those fields in the primary key must be public and not
+ static. And each must match a field with the same type and same
+ name in the bean implementation. Each of the matching fields
+ in the bean implementation must also be public and not static.
+ Finally, your primary key class must override <code>equals</code>
+ and <code>hashCode</code> from <code>java.lang.Object</code> and
+ make them correctly identify two primary keys that represent the
+ same entity.</p>
+ <p>It is worth repeating that in the latter case where you create
+ your own primary key class, your bean class must declare fields of
+ the types that make up the primary key class, not a field with
+ the type of the primary key class itself. Or at least, if you
+ do create a field of the type of the primary key class itself, you
+ should not make that field a container-managed field.</p>
+
+ <h4><a NAME="cmpfind">Finders for CMP Beans</a></h4>
+ <p>JAWS will automatically create finders for
+ <code>findByPrimaryKey</code>, <code>findAll</code>, and
+ <code>find<i>Attribute</i></code> where Attribute is a
+ container-managed field. For finders that return multiple
+ results, you can choose in your home interface whether to return
+ Collections (Java 2+) or Enumerations (Java 1+), and JAWS will
+ create them accordinaly. If you want to create additional
+ finders, you have two options.</p>
+ <p>First, you can declare them in your home interface and then
+ create finder definitions in your JAWS deployment descriptor
+ (see <a HREF="BROKENLINK">The JAWS Deployment Descriptor</a>).
+ This is suitable for queries that only involve the table your
+ entity bean is stored in: effectively, you can write the WHERE
+ clause of a SQL query, but the FROM clause is fixed.</p>
+ <p>Second, you can implement the finders yourself, even if the rest
+ of your bean uses CMP. This is best for complex queries that
+ require other tables. Any time you implement a finder yourself
+ (even for the default finders mentioned above), JAWS will use it
+ rather than ignoring it. But you probably don't want to do that
+ unless you really need to.</p>
+
+ <h3><a NAME="bmp">BMP Entity Beans</a></h3>
+ <p>For BMP entity beans, you are in control of the persistence of
+ the bean. You must write all the persistence code yourself. On
+ the other hand, you can create a more advanced persistence scheme
+ than may be possible with CMP beans. For example, you bean may
+ use multiple data sources, use multiple tables, or implement
+ persistence via JMS, a legacy API, etc.</p>
+ <p>Since the persistence is left up to you, there are no particular
+ requirements on the fields of the bean implementation. You may
+ choose not to even use fields for some of the persistent data - it
+ may be calculated on the fly, looked up elsewhere, or whatever.
+ With BMP you definitely have more control over the persistence of
+ your beans, but more work to do as well.</p>
+
+ <h4><a NAME="bmppk">Primary Keys for BMP Beans</a></h4>
+ <p>There are fewer rules for BMP primary keys. They must still be
+ public, non-abstract, <code>Serializable</code>, and implement
+ <code>equals</code> and <code>hashCode</code>. Beyond that, the
+ implementation is up to you.</p>
+
+ <h4><a NAME="bmpfind">Finders for BMP Beans</a></h4>
+ <p>You are in charge of finders for BMP beans as well. You must
+ implement all the finders declared in the bean's home interface.
+ If you're using Java 2 they may return Collections as well as
+ Enumerations for finders that return multiple results.</p>
+
+ <h2><a NAME="session">Session Beans</a></h2>
+ <p>jBoss supports both Stateful and Stateless session beans.
+ Stateful beans will associate one bean with one client until
+ the client releases it, while stateless beans may be shared
+ among a number of clients. jBoss creates a pool of beans to
+ share between clients, to reduce the memory usage of the server
+ as a whole. To change the pooling characteristics of a session
+ bean, you need to change the deployment descriptor (see
+ <a HREF="BROKENLINK">The jBoss Deployment Descriptor</a>).</p>
+
+ <h2><a NAME="env">Using Environment Settings</a></h2>
+ <p>If you need to pass configuration information to your beans, you
+ can use environment settings. Basically, you choose a variable
+ name and type, and code your bean accordingly. Then when you go
+ to deploy the bean, you specify environment settings in the
+ deployment descriptor (see
+ <a HREF="BROKENLINK">The EJB 1.1 Deployment Descriptor</a>). In
+ this manner you can deploy one bean multiple times with different
+ settings, change the settings between servers, etc.</p>
+ <p>To access an environment setting in an EJB (any type, entity,
+ session, etc.), you get the value out of JNDI. You can't
+ generally do this in the bean constructor, so you should do it in
+ the <code>setXXXContext</code> method, or when you actually need
+ to use the setting. The variables are stored in the
+ <code>java:comp/env</code> namespace, so for a variable called
+ <code>foo</code> (of type <code>int</code>, let's say), you'd use
+ code like this:</p>
+<pre>
+ Context ctx = new InitialContext();
+ int foo = ((Integer)ctx.lookup("java:comp/env/foo")).intValue();
+</pre>
+
+
+ <h2><a NAME="data">Using Data Sources</a></h2>
+ <p>Like Environment Settings, data source are configured in the
+ deployment descriptor (see
+ <a HREF="BROKENLINK">The EJB 1.1 Deployment Descriptor</a>).
+ They are also stored under the <code>java:comp/env</code>
+ namespace. The EJB specification recommends that you begin the
+ name of your data source with "<code>jdbc/</code>", but that is
+ not required. jBoss will <em>not</em> automatically add the
+ <code>jdbc/</code> prefix; you must include it in the name of your
+ Data Source if you want it to be there.</p>
+ <p>For example, let's say you configured a data source called
+ <code>jdbc/OracleDB</code> in your deployment descriptor. The
+ bean would access it using code like the example below. Note that
+ you should preform this lookup every time you require data
+ access, rather than storing the DataSource or Connection in an
+ instance variable (unless it's part of the state of a Stateful
+ Session Bean). Also, be sure you close the connection at the
+ end of the method, unless you have a very good reason not to.
+ This won't really close the connection - just return it to the
+ connection pool - but you want to avoid a "connection leak" at
+ all costs!</p>
+<pre>
+ Context ctx = new InitialContext();
+ Connection conn = null;
+ try {
+ DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/OracleDB");
+ conn = ds.getConnection();
+ ...
+ } catch(NamingException ne) {
+ ...
+ } catch(SQLException se) {
+ ...
+ } finally {
+ if(conn != null)
+ try {conn.close();} catch(SQLException e) {}
+ }
+</pre>
+
+ <h2><a NAME="ejbs">Using Other EJBs</a></h2>
+ <p>Once again, if you use other EJBs, you access them via JNDI and
+ the <code>java:comp/env</code> namespace. Even if the beans are
+ deployed on the same server and you think you could access them
+ directly, it's better to configure an EJB reference in your
+ deployment descriptor (see
+ <a HREF="BROKENLINK">The EJB 1.1 Deployment Descriptor</a>).
+ The EJB specification recommends that you begin the name of your
+ EJB reference with "<code>ejb/</code>", but that is not required.
+ jBoss will <em>not</em> automatically add the <code>ejb/</code>
+ prefix; you must include it in the name of your EJB reference if
+ you want it to be there.</p>
+ <p>For example, let's say you want the current EJB to use another
+ bean known as UtilityBean. That bean may be located in JNDI under
+ the name <code>Utility</code>, but you set up an EJB reference for
+ your bean to use, and call it <code>ejb/MyUtility</code>. Then
+ the code to access the bean would look like the following:</p>
+<pre>
+ Context ctx = new InitialContext();
+ UtilityHome home = (UtilityHome)ctx.lookup("java:comp/env/ejb/MyUtility");
+ Utility util = home.create();
+</pre>
+
+ <h2><a NAME="trans">Transactions</a></h2>
+ <p>There are three approaches to transactions. In any of these
+ cases, jBoss will handle propogating the current transaction to
+ other beans or data sources you use, subject to their
+ transaction configuration. The different between the three
+ approaches is what is responsible for creating transactions,
+ and then committing or rolling back when the work has
+ finished.</p>
+ <p>The first option is container-managed transaction demarcation.
+ In this case, you can let jBoss handle everything. You specify
+ the transaction settings for each bean method in the deployment
+ descriptor (see
+ <a HREF="BROKENLINK">The EJB 1.1 Deployment Descriptor</a>). In
+ this case jBoss handles creating, committing, and rolling back
+ transactions.</p>
+ <p>The other two options, bean-demarcated transactions and
+ client-demarcated transactions, are closeley related. In these
+ cases, you must manually handle creating, committing, and rolling
+ back transactions. In bean-demarcated transactions, your bean
+ manages the transactions, while in client-demarcated transactions,
+ your client manages the transactions. Not all types of clients
+ will necessarily be able to access or manage transactions,
+ however.</p>
+ <p>To manually manage transactions, you need to access an instance
+ of <code>javax.transaction.UserTransaction</code>. One option is
+ to get it from JNDI under the name
+ <code>comp:java/env/UserTransaction</code>. The other is only
+ applicable to EJBs. An EJB can use the
+ <code>getUserTransaction()</code> method of its
+ <code>EJBContext</code>.</p>
+ <p><i><b>Note:</b> The current jBoss beta does not allow JNDI
+ access, so client-demarcated transactions are not
+ possible.</i></p>
</body>
</html>
1.6 +13 -10 jbossweb/manual/index.html
Index: index.html
===================================================================
RCS file: /products/cvs/ejboss/jbossweb/manual/index.html,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- index.html 2000/09/16 12:34:16 1.5
+++ index.html 2000/09/16 18:54:34 1.6
@@ -61,16 +61,19 @@
<p CLASS="tc2"><a CLASS="plain" HREF="start_stop.html#script">Stopping with
the Shutdown Script</a></p>
<p CLASS="tc2"><a CLASS="plain" HREF="start_stop.html#jmx">Stopping via the
Management Interface</a></p>
<p CLASS="tc1"><a CLASS="plain" HREF="developing.html">Writing EJBs</a></p>
- <p CLASS="tc2">jBoss Supports EJB 1.1</p>
- <p CLASS="tc2">Entity Beans</p>
- <p CLASS="tc3">CMP Entity Beans</p>
- <p CLASS="tc4">Primary Keys for CMP Beans</p>
- <p CLASS="tc3">BMP Entity Beans</p>
- <p CLASS="tc4">Primary Keys for BMP Beans</p>
- <p CLASS="tc2">Session Beans</p>
- <p CLASS="tc2">Using Data Sources</p>
- <p CLASS="tc2">Using other EJBs</p>
- <p CLASS="tc2">Transactions</p>
+ <p CLASS="tc2"><a CLASS="plain" HREF="developing.html#ejb11">jBoss Supports
EJB 1.1</a></p>
+ <p CLASS="tc2"><a CLASS="plain" HREF="developing.html#entity">Entity
Beans</a></p>
+ <p CLASS="tc3"><a CLASS="plain" HREF="developing.html#cmp">CMP Entity
Beans</a></p>
+ <p CLASS="tc4"><a CLASS="plain" HREF="developing.html#cmppk">Primary
Keys for CMP Beans</a></p>
+ <p CLASS="tc4"><a CLASS="plain" HREF="developing.html#cmpfind">Finders
for CMP Beans</a></p>
+ <p CLASS="tc3"><a CLASS="plain" HREF="developing.html#bmp">BMP Entity
Beans</a></p>
+ <p CLASS="tc4"><a CLASS="plain" HREF="developing.html#bmppk">Primary
Keys for BMP Beans</a></p>
+ <p CLASS="tc4"><a CLASS="plain" HREF="developing.html#bmpfind">Finders
for BMP Beans</a></p>
+ <p CLASS="tc2"><a CLASS="plain" HREF="developing.html#session">Session
Beans</a></p>
+ <p CLASS="tc2"><a CLASS="plain" HREF="developing.html#env">Using
Environment Settings</a></p>
+ <p CLASS="tc2"><a CLASS="plain" HREF="developing.html#data">Using Data
Sources</a></p>
+ <p CLASS="tc2"><a CLASS="plain" HREF="developing.html#ejbs">Using Other
EJBs</a></p>
+ <p CLASS="tc2"><a CLASS="plain"
HREF="developing.html#trans">Transactions</a></p>
<p CLASS="tc1"><a CLASS="plain" HREF="deploying.html">Deploying EJBs in
jBoss</a></p>
<p CLASS="tc2">Preparing Your EJB JAR</p>
<p CLASS="tc3">Required Classes</p>
1.6 +2 -1 jbossweb/manual/warning.html
Index: warning.html
===================================================================
RCS file: /products/cvs/ejboss/jbossweb/manual/warning.html,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- warning.html 2000/09/16 12:34:17 1.5
+++ warning.html 2000/09/16 18:54:34 1.6
@@ -65,7 +65,8 @@
</li>
<li>Writing EJBs
<ul>
- <li>This section must be written</li>
+ <li>Can CMP entities have primitive simple PKs?</li>
+ <li>Confirm Transaction content.</li>
</ul>
</li>
<li>Deploying EJBs in jBoss