Automatic generation of unique primary keys

This article describes how to automatically generate unique primary keys for your EJB Entities.

1 Introduction

    Sometimes it is useful to have primary keys that holds no information of value besides making the Entity unique. Many different techniques exist to automate this process. This article will describe some of these techniques and try to present the pro and cons of using them.

2 Counter utility

    Automatic generation of unique primary keys can be performed by using a counter utility that keeps track of the current highest value of used primary key. When a new value is requested the counter utility increases the current highest value.

    One such counter utility is the counter.jar EJB-module produced by IronFlare. This EJB-module can be included in the users application and then referenced when a unique long value is needed. In order to be as effective as possible, the EJB-module gets a series of values to hold on to during its lifetime and to handle out on request. When these values are all used up, the EJB-module gets a new series of unique values. This limits the number of requests against the underlying DataSource to a minimum.


    public Long ejbCreate()
    {
    try
    {
    setId(CounterUtils.getNextID(
    "java:comp/env/ejb/counter",
    "thisEntity"));
    }
    catch (RemoteException e)
    {
    throw new EJBException(e);
    }
    return null;
    }

    Listing 1: Example usage of the counter.jar counter utility from inside the ejbCreate method of an Entity bean

    The drawback of using such a counter utility is that they have a limitation on the number of unique keys they can produce. On the other hand, referencing the key is very easy.

3 Container generated

    It is required by the EJB specification that the Container should be able to automatically generate unique primary keys using Object as key for CMP Entity beans. This is very useful when you don't need to show the primary key to the client or have the client select a primary key.

    In order for the Container to generate primary keys for an CMP Entity the following is required:

      The ejbCreate method should have a return type of java.lang.Object and return null.

      The <persistence-type> tag should contain a value of Container in the ejb-jar.xml entry for the entity

      The <prim-key-class> tag should contain a value of java.lang.Object in the ejb-jar.xml entry for the entity

      The <primkey-field> should not be given in the ejb-jar.xml entry for the entity

    Using this approach to generate unique primary keys is very nice as long as you don't have to reference the primary key itself, as the underlying type represented by Object is decided by the Container at deployment time.

    This also means that you should not have any implementation methods that use the primary key or rely on methods that have to reference it.


    public Object ejbCreate(Date date,
    String sourceAccountId,
    String targetAccountId,
    String event) throws CreateException
    {
    this.setDate(date);
    this.setSourceAccountId(sourceAccountId);
    this.setTargetAccountId(targetAccountId);
    this.setEvent(event);
    return null;
    }
    Listing 2: Example ejbCreate method for a CMP Entity relying on Container generated primary key


    <entity>
    <display-name>mainLog</display-name>
    <ejb-name>mainLog</ejb-name>
    <local-home>com.acme.atm.ejb.MainLogHome</local-home>
    <local>com.acme.atm.ejb.MainLog</local>
    <ejb-class>com.acme.atm.ejb.MainLogEJB</ejb-class>
    <persistence-type>Container</persistence-type>
    <prim-key-class>java.lang.Object</prim-key-class>
    <reentrant>False</reentrant>
    <abstract-schema-name>MainLog</abstract-schema-name>
    <cmp-field>
    <field-name>date</field-name>
    </cmp-field>
    <cmp-field>
    <field-name>sourceAccountId</field-name>
    </cmp-field>
    <cmp-field>
    <field-name>targetAccountId</field-name>
    </cmp-field>
    <cmp-field>
    <field-name>event</field-name>
    </cmp-field>
    </entity>
    Listing 3: Example ejb-jar.xml entry for a CMP Entity relying on Container generated primary key

    For more information please see the ATM J2EE application sample shipped with Orion it uses this functionality for two of its Entities, MainLog and LogEntry.

Copyright © 2005 IronFlare AB