Using EJB3 JPA to Map multi-level entity inheritance to a single table
EJB3 specification was finalized few weeks back and now EJB3 and JPA are in action and many companies have developing their next generation applications using EJB3 and JPA.  OnJava published my article on EJB3 JPA few weeks back and I got some follow up questions from readers and customers.  Can you map an entire hierarchy of objects with multi-level inheritance into a single table? In my article, I discussed a single level of inheritance and will use the same domain model to add another level. Let us start with a simple top-level domain object Employee. There may be two type of employees: FullTime and Contractor and hence FullTime and Contractor inherit from Employee object. Let us assume that there are two types of contractors: Consultant who charges hefty amount and Volunteer who works for free and hence Consultant and Volunteer inherit from Contractor object and hence the inheritance will look like follows: Let us assume that you want to map the entire hierarchy of objects into a single table named EMP table.   Assuming you do not to persist an instance of Employee as is, we defined it to be an abstract entity and defined that it is mapped to EMP table and we have defined the inheritance strategy to SINGLE_TABLE. We have defined the discriminator column to be EMPLOYEE_TYPE that stores the employee type: F for fulltime, C for Consultant and V for volunteer. Note that Id and Table mapping can be defined only in the top-level entity in a hierarchy as follows when using SINGLE_TABLE inheritance strategy:  @Entity@Table(name="EMP")@Inheritance(strategy=InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(name="EMPLOYEE_TYPE",discriminatorType=DiscriminatorType.STRING, length=1)public abstract class Employee implements Serializable {    @Id    @GeneratedValue(strategy=GenerationType.AUTO)    @Column(nullable=false)    protected Long empNo;    @Column(name="ENAME")    protected String name;    protected Timestamp hireDate;    protected String job;    ..} The FullTime entity extends the employee and can be persisted on its own. We define the DiscriminatorValue for this entity to be 'F' @Entity@DiscriminatorValue(value="F")public class FullTime extends Employee {public FullTime() {    }    @Column(name = "SAL")    private Double salary;    @Column(name = "COMM")    private Double commission;    @Column(name = "DESIG")    private String designation;..} The Contractor entity extends Employee but is not persistence on its own, instead its sub-type Consultant and Volunteer are persisted. Hence there is no discriminator value defined for the Contractor entity: @Entitypublic abstract class Contractor extends Employee  {  @Column(name = "END_DATE")
   private Timestamp endDate; ..} The discriminator value for Consultant and Volunteer entities are defined as follows: @Entity@DiscriminatorValue(value="C")public class Consultant extends Contractor {    public Consultant() {..}              @Entity@DiscriminatorValue(value="V")public class Volunteer extends Contractor implements Serializable {    public Volunteer() {    }..}   We are done with the mapping ! Now let us create a session façade for the Employee entity  @Stateless(name="EmployeeFacade")                                   public class EmployeeFacadeBean implements EmployeeFacade {    @PersistenceContext    private EntityManager em;     public EmployeeFacadeBean() {    }     public Object mergeEntity(Object entity) {        return em.merge(entity);    }    public Object persistEntity(Object entity) throws EmployeeCreationException{        em.persist(entity);        return entity;    } ..  } Let us create a client that uses the session facade persists each type of Employee instances and then list using a named query. You can use dependency injection to invoke the bean instance as follows:              @EJB            EmployeeFacade employeeFacade;       // Persist a FullTime Entity            FullTime fte = new FullTime();            fte.setName("PNisheet");            fte.setSalary(new Double(1200.0));            fte.setDesignation("Programmer");                        employeeFacade.persistEntity(fte);                      // Persist a Consultant             Consultant pte = new Consultant();            pte.setName("PandaB");            pte.setHourlyRate(new Double(100.0));            employeeFacade.persistEntity(pte);                       //Persist a Volunteer            Volunteer vol = new Volunteer();            vol.setName("RenuMi");            vol.setDesignation("Trainee");            employeeFacade.persistEntity(vol);                        // List All employees            List<Employee> emplist = employeeFacade.findAllEmployee(); We are done. After running the the client you will see each entity instance persisted to the EMP table with appropriate EMPLOYEE_TYPE column set.  EMPNO ENAME      EMPLOYEE_TYPE
----- ---------- -------------
 1506 RenuMi     V
 1504 PNisheet   F
 1505 PandaB     C Hope this helps!10:28:06 AM    comment [1]    Tuesday, May 30, 2006 
Back from Alaska Cruise, battery recharged
I took a break from work last week and went for a weeklong cruise trip to Alaska with my family. It was a nice break from work and relaxing. Now I feel as if I got my battery recharged!  Alaska is beatiful too. I can抰 believe I did not browse web or read emails (cell phone switched off, isn't that nice?) for six days! Now I抳e hundreds of emails in my Inbox. I tried the high-speed Internet on the vessel from the cruise on my final day on cruise and it was worse than a dialup. It was expensive, $16 for half-hour and all I could do is write only three e-mails!Anyway back to work and will soon resume regular tech blogging!6:22:54 AM    comment [1]    Thursday, May 18, 2006 
Article: EJB3 Java Persistence API
EJB3 became final few days back. OnJava just published my article Standardizing Java Persistence API with EJB3 JPA. This article provides an introduction to what EJB3 JPA is bringing onto the table.11:51:16 AM    comment [3]    Monday, May 15, 2006 
First Taste of EJB: Sample Chapter from "EJB3 In Action"
"In this age of hyper-competitiveness, learning a new technology by balancing a book on your lap while hacking away at the business problem on the keyboard has become the norm. But let抯 face it梥omewhere deep down, you probably prefer "baptism by fire." This Chapter is for the brave pioneer in all of us, who can take a quick look at all the EJB types  .." The early draft of Chapter 2: First Taste of EJBs of our upcoming book EJB3 In Action   is now available at Manning Website. This introduces different types of EJBs: Session beans, MDBs and Entity.  Please review and give us your honest feedback.