EJB Inheritance, Part 2

EJB Inheritance, Part 2

One-Table Mapping



As its name indicates, one-table mapping involves a single table, including rows belonging to all classes of the hierarchy. This single table must then have a special column to specify what kind of object is being stored in the rows. This column can bear many names: category, type, kind, class, variety, brand, sort, etc.

Here's the database schema for our RTM database.


Figure 3. One-table mapping database schema

We've introduced the Category field here, which can hold one of three values: "B" (base customer), "G" (Gold customer), and "P" (Platinum Customer). This field is pretty much useless in our business logic, but we still need to declare it to code the queries, as we'll see shortly. Don't forget to initialize this field in ejbCreate(), for the base class and all subclasses. The BaseCustomerBean class sets the field to "B," the GoldCustomerBean class sets the field to "G," and the PlatinumCustomerBean class sets the field to "P."

In this kind of table mapping, a single table contains all fields of all objects in the whole hierarchy. Fields that are not used in a certain row are simply left null. For example, the Charity field is not used by base and gold customers. This technique does produce a lot of null fields, but it shouldn't be a problem.

The locate methods for this table-mapping technique are the same as in the horizontal mapping, so I'll skip this part.

But there is one problem introduced by this table mapping. Finder methods don't behave as they should. Imagine a situation where there's a regular customer with customer ID of "123." Finding a gold customer using this same key will return a (wrong) result! There has to be a way to filter out the other kinds of customers when querying the database. In this example, it would mean ignoring regular and platinum customers when finding a gold customer.

Working around this problem is easy, in most cases. Just add a condition at the end of every EJB-QL query, like this:

EJB-QL Query for Base customers:

SELECT OBJECT(c) FROM BaseCustomerEJBOneTable AS c 

    WHERE c.category = 'B'

EJB-QL Query for Gold customers

SELECT OBJECT(c) FROM GoldCustomerEJBOneTable AS c 

    WHERE c.category = 'G'

EJB-QL Query for Platinum customers

SELECT OBJECT(c) FROM PlatinumCustomerEJBOneTable AS c 

    WHERE c.category = 'P'

But what about findByPrimaryKey()? The container writes this method for you. How do you filter out the unwanted rows? Once more, the only way to work around this problem is to rely on a feature of your application server.

WebLogic Server 7 allows overwriting findByPrimaryKey() using a WebLogic-QL query in weblogic-cmp-rdbms-jar.xml. I'm using this trick in my RTM example. Other vendors may tackle this in other ways. Some may allow manually writing this query in ejb-jar.xml, although that may go against the specification. Some may not support this feature at all, which makes one-table mapping impossible.

Assessment: This kind of table mapping is often used with a legacy database, which typically has tables with category columns. It requires that the application server provide a way to filter out the rows that are not wanted when running the queries.

Conclusion and Acknowledgments

I didn't invent any of this. Many products exist out there which allow us to use these three techniques (and others) when mapping database tables to hierarchies of classes. I merely applied the three techniques to the special case of entity beans, working around problems as I went.

I specifically want to credit Apple's Enterprise Object Framework (EOF) toolkit for its ingenuity in this field, which inspired me. EOF is a library and tools to map database tables to straight Java (and Objective-C) objects. The maturity of this framework, its flexibility, and its simplicity should be a model for any persistence services provider.

Also worth highlighting, WebLogic Server 7 provided me with all the features needed in order to implement my work-arounds. Kudos to BEA.

Don't get cranky if I didn't mention your favorite persistence services provider tool. I know there are others out there, I just can't explore them all in these few lines.

Next time, we'll see examples of session beans and message-driven beans that use inheritance.

Emmanuel Proulx is an expert in J2EE and Enterprise JavaBeans, and is a certified WebLogic Server 7.0 engineer. He works in the fields of telecommunications and web development.


Return to ONJava.com.

Prev  [1] [2] [3] 

Close    To Top
  • Prev Article-Java:
  • Next Article-Java:
  • Now: Tutorial for Web and Software Design > Java > JavaBeans > Java Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction