Entity Bean Design Issues

Discussions

EJB design: Entity Bean Design Issues

  1. Entity Bean Design Issues (1 messages)

    There are two issues in this message that I was wondering if anyone had good solutions for.

    ----------------------------------------------------------

    I have a project where I have polymorphic objects. So, for the sake of clarity we'll adopt this hierarchy:

    VEHICLE
        CAR
        BOAT
        PLANE

    They share primary keys in our database. (So, the primary key of the vehicle is the same as the primary key of the corresponding table for car/boat/plane)

    (I have no way of mutating the database in any significant manner)

    So, if the system finds a "car" by primary key, all should be fine. But what happens if the system tries to find a "vehcile" by primary key??? How should I handle the logic to return a car bean over a vehicle bean in the home interface?

    The way our current "object" system is doing it is that there is a type id in the parent level class (vehcile) that determines what type of vehicle it is. I could repeat this style of logic, but is there a better (EJB supported) way of doing this?

    Should the EJBs be inherited from one another, or should I use a "has-a" relationship and loose polymorphic ability if someone makes the vehicle?


    ----------------------------------------------------------

    The second question is a bit more interesting, I think:

    I have a set of data that can be in multiple persistent stores at the same time. In other words:

    VEHICLE (DB1)
      128 MyVehicle

    VEHICLE (DB2)
      128 MyOtherVehicle

    The EJB system I am developing must handle this situation and allow both vehicles to be loaded and worked on idependently. This is leading me to using a primary key like this:

    class VehiclePK
    {
       public String schemaName;
       public int id;
    }

    And code the find/create methods to build some sort of a helper object to do the db creation/insertion/update.

    Is there a better method of doing this that is consistent with the EJB model?

    ---------------------------------------------------------

    If you need more information, I'll be happy to provide it.

    Thanks for any help you folks can provide,

    Alan Wood
    alan_wood at yahoo dot com

  2. Entity Bean Design Issues[ Go to top ]

    Hi Alan!

    Great questions and they really make you think. I believe I have a good answer for your first question. The answer may get a little involved, but I have used this implementation on many projects and I consider it a "back door" answer to a common problem that you and many others are facing.

    One of the things that you have to keep in mind if you attempt to do EJB inheritance is that if you have a Car EJB, the create() method in the home interface has to return Car. So, if you had a VehicleHome with:

    Vehicle create() throws CreateException, RemoteException;

    You cannot have your CarHome extend VehicleHome since the create() method that you write MUST return Car.

    Bummer, right? Well, not necessarily.

    If you are trying to represent inheritance, there is a little trick that you can pull off. First, you will need to have separate Remote and Home interfaces for all of your EJBs and none of the interfaces can extend one another. What you do, however, is to make sure that all of the create(...) or find(...) methods take the same input arguments in each interface. So, if your VehicleHome has:

    Vehicle create(int id, String make)

    Make sure your CarHome has:

    Car create(int id, String make)

    If you want, you can have ADDITIONAL create(...) methods in your sub-interfaces, but at a minimum you must include exact replicas of every create(...) / find(...) method in the base home interface. To

    You can implement each bean however you want and you can possibly use implementation inheritance between VehicleBean and CarBean, but that doesn't really matter. Since the container will consider each bean separate, you can map the fields to any column in any database that you want.

    The interesting part is in the client that uses the EJB. Since all of the EJBs have the same methods in their home interfaces, you can use introspection to load / create a bean. The pseudo code for this would be:

    EJBOBject getBean(String whichBean) {
      // Since EJBs are deployed to different JNDI names
      // You still need to know whether you are going to
      // access a car, vehicle, or what. I tend to recommend
      // storing a static array of names to JNDI names or
      // you can use an XML file, too.
      Look up JNDI name from XML file.
      EJBHome home = (EJBHome)ctx.lookup("SomeBean");
      
      Do introspection on 'home' to locate create(...) method.
      // Since all of the home interfaces that you defined
      // will have the same create(...) method with the same
      // argument types, you will be successful in locating
      // the reflection method.
      Use reflection to invoke the create or find method
      EJBObject remote = java.lang.reflect.Method.invoke(...);

      return remote;
    }

    Now, in the client that called the function, you can use the instanceof operator to test whether the EJBObject returned was a car, vehicle, or boat and then cast it appropriately.

    The only issue that I see with your example is that you'll have a Vehicle PK and will want to locate a Car. The issues that EJBs still pose is that in order to work with CarHome, you will need to know that you are working with Cars. For your particular situation, I would recommend creating a compound primary key that has the vehicleID and the a typeID. In the method that I gave above, you can parse the typeID to discover which string you should pass into the JNDI lookup. After that, the reflection logic will give you everything else you need.

    Let me know you if you have any questions.
    Tyler