Table per Concrete Class






Table per Concrete Class

In the table per concrete class strategy, a database table is defined for each concrete class in the hierarchy. Each table has columns representing its properties, and all properties of any superclasses.

create table Person (
   id integer primary key not null,
   firstName varchar(255),
   lastName varchar(255),
);

create table Customer (
   id integer primary key not null,
   firstName varchar(255),
   lastName varchar(255),
   street varchar(255),
   city varchar(255),
   state varchar(255),
   zip varchar(255),
);

create table Employee (
   id integer primary key not null,
   firstName varchar(255),
   lastName varchar(255),
   street varchar(255),
   city varchar(255),
   state varchar(255),
   zip varchar(255),
   employeeId integer,
);

One major difference between this strategy and the SINGLE_TABLE strategy is that no discriminator column is needed in the database schema. Also notice that each table contains every persistent property in the hierarchy. Let's now look at how we map this strategy with annotations:

@Entity
@Inheritance(strategy=InheritanceType 
.TABLE_PER_CLASS)
 

public class Person {
...
}

@Entity
public class Customer extends Person {
...
}

@Entity
public class Employee extends Customer {
...
}

Notice that the only inheritance metadata required is the InheritanceType, and this is needed on only the base Person class.

Let's look at the XML mapping for this strategy type:

<entity-mappings>
   <entity class="com.titan.domain.Person">
   <inheritance strategy="TABLE_PER_CLASS"/>
      <attributes>
         <id>
            <generated-value/>
         </id>
      </attributes>
   </entity>
   <entity class="com.titan.domain.Customer"/>
   <entity class="com.titan.domain.Employee"/>
</entity-mappings>

Like their annotation counterparts, the metadata you have to describe is pretty sparse if you rely on default attribute mappings. All we need is the <inheritance> element defined with TABLE_PER_CLASS in the root of the class hierarchy.

Advantages

The advantage to this approach over the SINGLE_TABLE strategy is that you can define constraints on subclass properties. Another plus is that it might be easier to map a legacy, preexisting schema using this strategy.

Disadvantages

This strategy is not normalized, as it has redundant columns in each of its tables for each of the base class's properties. Also, to support this type of mapping, the persistence manager has to do some funky things. One way it could be implemented is for the container to use multiple queries when loading an entity or polymorphic relationship. This is a huge performance hit because the container has to do multiple round trips to the database. Another way a container could implement this strategy is to use SQL UNION s. This still would not be as fast as the SINGLE_TABLE strategy, but it would perform much better than a multiselect implementation. The downside to an SQL UNION is that not all relational databases support this SQL feature. It is probably not wise to pick this strategy when developing your entity beans, unless you absolutely have to.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows