Nice work, Floyd. I think this chapter will be valuable to EJB developers.  One thing I would change is to use Java RMI's UUID generator (java.rmi.dgc.VMID) instead of creating a custom one -- its already there so why not use it? I did, however, enjoy your explanation of UUID and I think people can learn a lot from that discussion.  As a side note: I would never use another enterprise bean as the id generator because the overhead is unwarranted.  Other then that I thought the chapter was excellent.

One problem with EJB 2.0 is that auto-generated primary keys are not explicitly accommodated in the CMP programming model. This is a problem that I have commented on several times over the past three years.  The largest barrier to auto-genterated primary keys today is that the spec now requires that primary key fields be set in the ejbCreate method for CMP beans.  If not for this requirement -- which means that the key value must be known by the bean provider during the ejbCreate method -- vendors could easily support auto-generated primary keys in a portable way.

It appears however that vendors are largely ignoring this requirement anyway in an effort to support auto-generated primary keys.  If the bean provider specifies a primkey-field (and its associated cmp-field), but doesn't set the primkey-field in the ejbCreate method, the vendor will allow the value to be auto-generated.   From what I can tell at least three vendors will support auto-generated keys in this way, which makes it a fairly portable if not specified feature.

Personally, I would like to see the EJB 2.0 team remove the requirement that the primary key fields be specified during the ejbCreate method. In addition, they should add an element to the entity XML deployment descriptor for CMP 2.0 that allows the bean developer to specify that a primary key can be auto-generated. For example the Customer EJB would be deployed as follows so that its id field is an auto-generated primary key.

<ejb-jar>
    <enterprise-beans>
    <entity>
        <ejb-name>CustomerEJB</ejb-name>
        <home>com.titan.customer.CustomerHomeRemote</home>
        <remote>com.titan.customer.CustomerRemote</remote>
        <ejb-class>com.titan.customer.CustomerBean</ejb-class>
        <persistence-type>Container</persistence-type>
        <prim-key-class>java.lang.Integer</prim-key-class>
        <reentrant>False</reentrant>
        <cmp-version>2.x</cmp-version>
        <abstract-schema-name>Customer</abstract-schema-name>
        <cmp-field><field-name>id</field-name></cmp-field>
        <cmp-field><field-name>lastName</field-name></cmp-field>
        <cmp-field><field-name>firstName</field-name></cmp-field>
        <primkey-field>id</primkey-field>
        <auto-generate-primkey>True</auto-generate-primkey>
        <security-identity><use-caller-identity/></security-identity>
    </entity>

The bean developer specifies that the primary key field is auto-generated by setting the optional <auto-generate-primkey> element to True (the default is false). The bean code would be as follows (notice that the id field is not set in the ejbCreate method):

public abstract class CustomerBean implements EntityBean {

    public Integer ejbCreate(String fName, String lName){
        setFirstName(fName);
        setLastName(lName);
        return null;
    }
    ...
}

The deployer can choose at deployment time whether to use auto-increment facilities of the database or to use the container's automatic key generator (probably UUID). In this way auto-generated primary keys are supported by CMP 2.0 in a portable way without requiring the bean developer to jump through a bunch of hoops to do it.  Since vendors are going to support auto-generated primary keys anyway, why not make it a part of the specification. Its long overdue.

Thanks,

Richard
--
Richard Monson-Haefel
Author of Enterprise JavaBeans, 3rd Edition  (O'Reilly 2001)
Co-Author of Java Message Service (O'Reilly 2000)
http://www.jMiddleware.com
 

Floyd Marinescu wrote:

Hey guys,

        I have posted a chapter on Primary Key Generation Strategies as part of the
EJB Design Patterns book project on TheServerSide.com.

        One of the strategies covered is the use of stored procedures as you guys
have recently been discussing. The other patterns covered provide beautiful
alternatives.  You can download it here:

http://www.theserverside.com/resources/patterns_review.jsp

        take care,

Floyd Marinescu

-----Original Message-----
From: A mailing list for Enterprise JavaBeans development
[mailto:[EMAIL PROTECTED]]On Behalf Of Dennis Djenfer
Sent: Sunday, August 26, 2001 7:05 AM
To: [EMAIL PROTECTED]
Subject: Re: Primary Key Generation

Thank you!

This was exactly what I was looking for. I had overlooked that the
CallableStatement
actually implements the PreparedStatement interface.

There are many discussion threads about how to generate primary keys for
ejb's, but most
of the solutions run into problem when it comes to clusted application
servers, because
they ultimately needs the database to synchronize the generation of keys. I
feel that
the solution below, where the database generates and returns the primary key
in one call
is a very effecient solutions that also solves the clustering problem. Any
comments on
that topic?

Again, thank you for the code example

// Dennis

Steve Muench wrote:

> | >     INSERT INTO yourtable(pk,y,z)
> | >     VALUES(yoursequence.nextval,?,?)
> | >     RETURNING pk INTO ?
>
> Dennis Djenfer wrote:
>
> | The SQL statement looks fine to me, but I don't know how to execute this
statement
> | from JDBC.
>
> Here's an example program.
>
> import java.sql.Connection;
> import java.sql.Types;
> import java.sql.SQLException;
> import java.sql.CallableStatement;
> import java.sql.DriverManager;
> public class Example  {
>   private static final String STMT = "BEGIN INSERT INTO
DEPT(deptno,dname,loc) "+
>                                      "VALUES(mydeptseq.nextval,?,?) "+
>                                      "RETURNING deptno INTO ?; END;";
>   public static void main(String[] args) {
>     Connection c  = null;
>     try {
>       Class.forName("oracle.jdbc.driver.OracleDriver");
>       c  =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL",
>                                        "scott","tiger");
>       CallableStatement s = c.prepareCall(STMT);
>       s.setString(1,"Example");
>       s.setString(2,"Sample");
>       s.registerOutParameter(3,Types.INTEGER);
>       s.execute();
>       int i = s.getInt(3);
>       System.out.println("Row inserted was assigned sequence number "+i);
>     }
>     catch(Throwable t) {
>       t.printStackTrace(System.err);
>     }
>     finally {
>       if (c!=null) try { c.close(); } catch(SQLException ignore){}
>     }
>   }
> }
>
> _____________________________________________________________________
> Steve Muench - Developer, Product Manager, XML Evangelist, Author
> "Building Oracle XML Applications" - www.oreilly.com/catalog/orxmlapp
>

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".


 
 

Reply via email to