EJB CMP/CMR example with JBoss+Xdoclet javacode 9085791

EJB CMP/CMR example with JBoss+Xdoclet

A concrete example, more details

Our example is taken from my Open Source BibTeXml project. In the JBoss container we have a main list of all publications, containing articles, books, conference proceedings, etc. It is basically a representation of a bookshelf. Let us focus on the entity bean that represents this list and its reference to the article bean, the bean managing all the articles. Aside from containing all publications, the publication bean also contains data that is common to all publications types, e.g. a note or a category field.

The publication bean has the following fields

  • a primary key publicationID (type String, represented by publication_id VARCHAR in the database)
  • a publicationType field (article, book, etc.)

Of course, here I omitted all the fields common to all publications for the sake of clarity.

The article bean has the following fields

  • a foreign-key publicationIDfk referring to the publicationID of the publication bean
  • Other article specific data fields, such as author, title, journal and year

We discuss the relevant code sections of the publication bean, BibliographyBean.java below:

/**
 * @ejb.bean name="Bibliography"
 *        jndi-name="BibliographyBean"
 *        type="CMP"
 *        primkey-field="publicationID"
 *        schema="BibtexmlSchema"
 *        cmp-version="2.x"
 *
 *  @ejb.persistence
 *   table-name="bibliography"
 *
 * @ejb.finder
 *    query="SELECT OBJECT(a) FROM BibtexmlSchema as a"
 *    signature="java.util.Collection findAll()"
 *
 * ... SKIPPED SOME MORE FINDER METHOD DEFINITIONS ...
 **/

Here the primary key field, the associated database column, the database table this bean represents, the EJB-QL schema and some finder methods are defined. Next follows the class definition:

public abstract class BibliographyBean implements EntityBean, BitexmlConstants
{
    protected EntityContext entityContext;

    /**
     * Sets the entityContext
     * @param javax.ejb.EntityContext the new entityContext value
     */
    public void setEntityContext(EntityContext entityContext)
    {
        this.entityContext = entityContext;
    }

    /**
     * Unsets the entityContext
     */
    public void unsetEntityContext()
    {
        this.entityContext = null;
    }

    /**
     * The  ejbCreate method for an article.
     * Only fills the compulsory article fields.
     * Use update to fill the remainder of the article fields, if necessary.
     *
     * @ejb.create-method
     */
    public java.lang.String ejbCreate(String publicationID,
        String author,
        String title,
        String journal,
        Integer year) throws javax.ejb.CreateException
    {
        try
        {
            // Create a new article row in article table using the article entity bean.
            // In the ejbPostCreate() we will take care off the CMR.
            ArticleLocalHome articleLocalHome = ArticleUtil.getLocalHome();
            ArticleLocal article =
                articleLocalHome.create(publicationID, author, title, journal, year);
        }
        catch (NamingException e)
        {
            System.out.println("Articlebean.ejbCreate()" + e);
        }
        // Set bibliography data itself
        setPublicationID(publicationID);
        setPublicationType(ARTICLE);
        return null;
    }

    /**
     * The container invokes this method immediately after it calls ejbCreate.
     *
     */
    public void ejbPostCreate(String publicationID,
                    String author,
                    String title,
                    String journal,
                    Integer year) throws javax.ejb.CreateException
    {
        // Add relation (CMR)
        try
        {
            // Create a new article object
            ArticleLocalHome articleLocalHome = ArticleUtil.getLocalHome();
            setArticle(articleLocalHome.findByPrimaryKey(publicationID));
        }
        catch (NamingException e)
        {
            System.out.println("Articlebean.ejbPostCreate()" + e);
        }
        catch (FinderException e)
        {
            System.out.println("Articlebean.ejbPostCreate()" + e);
        }
    }

Remarks:

  • The System.out.println() is bad programming practice and should be replaced by Log4j calls. At the time of writing the code, this wasn’t operational yet under my JBoss configuration.
  • The errors should preferrably be propagated, instead of handled locally. This way the client cannot find out what went wrong if something did not go well
  • The (container) context is store upon creation, so that it may be retrieved later
  • Note the creation of the BibliographyBean itself (including setting the compulsory fields), the creation of the ArticleBean, and the setting of the CMR field in the Bibliographybean in the ejbPostCreate() method

Finally, we list the definitions of both CMP primary field and CMR field

    /**
     *
     * @return the associated entry in the article table
     *
     * @ejb.interface-method
     *
     * @ejb.relation
     *    name="bibliography-may-contain-article"
     *    role-name="BibliographyToArticle"
     *    cascade-delete="yes"
     *    target-cascade-delete="yes"
     *    target-role-name="ArticleToBibliography"
     *    target-ejb="Article"
     *
     * @jboss.target-relation
     *    related-pk-field="publicationID"
     *    fk-column="publication_id_fk"
     */
    public abstract ArticleLocal getArticle();

    /**
     *
     * @return
     *
     * @ejb.interface-method
     */
    public abstract void setArticle(ArticleLocal article);

    /**
     * Returns the publicationID
     * @return the publicationID
     *
     * @ejb.persistent-field
     * @ejb.persistence
     *    column-name="publication_id"
     *    sql-type="VARCHAR"
     * @ejb.pk-field
     * @ejb.interface-method
     *
     */
    public abstract java.lang.String getPublicationID();

    /**
     * Sets the publicationID
     *
     * @param java.lang.String the new publicationID value
     *
     * @ejb.interface-method
     */
    public abstract void setPublicationID(java.lang.String publicationID);

Apart from the primary key field, all other details have already been address in the previous (abstract/theory) section.

14 Comments

  1. CMR October 26, 2006
  2. Carola December 22, 2005
  3. Jens Wurm November 17, 2005
  4. Breno Leitao February 24, 2005
  5. Arne v.Irmer December 6, 2004
  6. Arne v.Irmer November 30, 2004
  7. Zeger Hendrikse November 23, 2004
  8. Arne v.Irmer November 23, 2004
  9. Arne v.Irmer November 23, 2004
  10. Zeger Hendrikse November 8, 2004
  11. Matt Robinson November 8, 2004
  12. ss October 19, 2004
  13. Janos Czako September 2, 2004
  14. Zeger Hendrikse August 2, 2004