Version 3

    Inheritance: Join Strategy

    CAUTION The information given in this section is wrong. JOINED inheritance does not need a discriminator column. Hibernate does not even support this. Hibernate uses a discriminator only for SINGLE_TABLE inheritance.

     

    The EJB specification allows you to define entities that inherit from one another.  The inheritance relationships can be reflected in

    queries as well.  So, if you queried based on the base class, the query is polymorphic.

     

    The tutorial example uses the join table strategy to map an inheritance relationship of Pet, which is the base class for Cat and Dog.

     

    With the join table strategy there is a table per class in the hierarchy, but the subclass tables only have the extra attribute they define in their subclass.  A discriminator column is required to differentiate between which class type is persisted in a particular row.

     

    This is what the annotations look like for Pet.

     

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED, discriminatorType = DiscriminatorType.STRING)
    @DiscriminatorColumn(name = "ANIMAL_TYPE", nullable = true)
    public class Pet implements java.io.Serializable
    {
    

     

    The @DiscriminatorColumn specifies the column that will hold the type of the persisted entity.  For subclasses, they must define the value of the discriminator column that will identify the class.

     

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED, discriminatorType = DiscriminatorType.STRING, discriminatorValue = "DOG")
    public class Dog extends Pet
    {
    

     

    Polymorphic Queries

    PetDAOBean stateless EJB wraps some polymorphic queries.

     

       public List findByWeight(double weight)
       {
          return manager.createQuery("from Pet p where p.weight < :weight").setParameter("weight", weight).listResults();
       }
    

     

    Even though the findByWeight method queries on Pet, either Dog or Cat instances can be returned.

     

    Table mapping

    The table mapping for this example looks like this:

     

    create table PET (
      ID integer primary key,
      ANIMAL_TYPE varchar,
      NAME varchar,
      WEIGHT double
    );
    
    create table CAT (
      ID integer primary key,
      LIVES int
    );
    
    create table DOG (
      ID integer primary key,
      NUMBONES int
    );
    

     

    To load subclasses the persistence manager must before a SQL join.  This is less efficient than the single table strategy as the SQL query is more complicated.

     

    Building and Running

    To build and run the example, make sure you have ejb3.deployer installed in JBoss 4.0.x and have JBoss running.  See the reference manual on how to install EJB 3.0. 

    Unix:    $ export JBOSS_HOME=<where your jboss 4.0 distribution is>
    Windows: $ set JBOSS_HOME=<where your jboss 4.0 distribution is>
    $ ant
    $ ant run
    
    run:
         [java] 2004-10-07 00:16:20,395 INFO org.jboss.remoting.InvokerRegistry[main] - Failed to load soap remoting transpo
    rt: org/apache/axis/AxisFault
         [java] Sox
         [java] Junior
    

     

    The INFO message you can ignore.  It will be fixed in later releases of JBoss 4.0.

     

    View the tables and rows

    You can view the tables created by JBoss by going to the Hypersonic SQL service, scrolling down to the startDatabaseManager button and clicking it.  A Hypersonic SQL window will be minimized, but you can open it up to look at the tables and do queries.

     

    Jar structure

    EJB 3.0 beans must be packaged in a JAR file with the suffix .ejb3.  Running the ant script above creates a JAR file within the deploy/ directory of JBoss.  All that needs to be in that jar is your server-side class files and additionally, you will probably need to define a hibernate.properties file in the META-INF directory of the JAR.  hibernate.properties is needed if you need to hook in a datasource other than JBoss's DefaultDS, or change the caching of Hibernate.  See the EJB 3.0 reference manual and Hibernate reference manual for more details.