Wednesday, December 4, 2013

Hibernate Tutorial - Part III

For previous parts refer:
Hibernate tutorial Part - I
Hibernate tutorial Part - II


Inheritance Mapping:

In this post, I'm going to write about Inheritance mapping in Hibernate.

Essentially, there are 3 different types of inheritance mapping which could be achieved:
  1. Table per concrete class 
  2. Table per class hierarchy
  3. Table per subclass

1. Table per concrete class

In this type of mapping, we will have a table mapped to every concrete class in the hierarchy. Lets say we have the following class hierarchy for representing different users of the system.

  • Abstract class, User
  • Concrete subclass, Customer
  • Concrete subclass, InternalUser
Lets take a look at the class definitions and the the annotations for each of these classes.

User Class:

@Entity
@Table(name = "USER") 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public class User implements Serializable{
     @Id    
     @Column(name = "USER_ID")
     private String userId;
     
     @Column(name = "USERNAME")
     private String userName;
     
     @Column(name = "PASSWORD")
     private String password;
     
     //setters and getters
}

Customer Class:

@Entity
@Table(name="CUSTOMER") 
    @AttributeOverrides({     
        @AttributeOverride(name="userName", column=@Column(name="FIRSTNAME")),     
        @AttributeOverride(name="password", column=@Column(name="LASTNAME")) })
public class Customer extends User implements Serializable{    
     @Column(name = "ADDRESS1")
     private String address1;
     @Column(name = "ADDRESS2")
     private String address2;
     @Column(name = "CITY")
     private String city;
     @Column(name = "STATE")
     private String state;
     @Column(name = "COUNTRY")
     private String country;
     
     //setters and getters
}

Internal User Class:

@Entity
@Table(name = "INTERNAL_USER") 
public class InternalUser extends User implements Serializable{
     /*Admin/Non Admin*/
     @Column(name = "ACCESSTYPE")
     private String accessType;
     /*Contract/Permament*/
     @Column(name = "EMPLOYMENTTYPE")
     private String employmentType;
     
     //setters and getters
}

Note:@Inheritance defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.

Table structure:
The table USER will have columns USER_ID,USERNAME,PASSWORD.
The table CUSTOMER will have all the columns as in USER plus additional columns.
The table INTERNAL_USER will have all the columns as in USER plus additional columns.

Notice that the primary key (USER_ID) is present in all the three tables and is shared across these tables.

Disadvantages of this approach:

  1. The columns in the super class are duplicated in all the child tables.
  2. Difficult to represent FK relationships. Lets say we have a class LoginDetails, which has association with User (either Customer or InternalUser). From a schema point of view, LOGIN_DETAILS table should have a FK to the CUSTOMER table or INTERNAL_USER table. We cannot represent this polymorphic representation effectively in SQL, as we will need two columns to represent this FK.
  3. Changes to the super class fields will cause changes to all the child class tables.
  4. The Sql to fetch child class will result in large number of selects.
  5. You cannot use AUTO/Identity column for the primary key.
                                                                                                 Continued...

No comments:

Post a Comment