Skip to main content

Inheritance Relationship

à1. Inheritance Mapping Model:
àBy using this ORM-mapping model we can resolve/solve the "Inheritance Impedance mismatch" problem.
àInheritance is again 2-types
1.  Generalization
2.  Realization

1.  Generalization:
Ex:
class Payment {
  protected String paymentId;
  protected String merchant;
  protected String amount;
  //setter and getters
}
àHere attributes of the Payment class need not to be protected they may even private also bcz Hibernate can inherit setters and getters. But to follow the convention we are taking protected and protected attributes can be inherited.
class CardPayment extends Payment {
  private String cardNo;
  private String cardType;
  private String cvv;
  private String expiry;
  //setter and getters
}
à Here CardPayment needs the same attribute of the Payment class hence we should not re-declare the all the attributes so we need to use Inheritance.
class ChequePayment extends Payment {
  private String checkNo;
  private String bank;
  private Date issueDate;
  //setter and getters
}
à We want to store the CardPayment details then we need to store the both Base class attribute and CardPayment (derived class attributes).
àIn order to store these information we can design tables in different ways as follows
àWe can persist all the class details in different tables that means every concrete class will have their own table hence it called as table per concrete class.
àConcrete class can carry the data but abstract or interfaces will not carry the data, bcz we can create obj only for concrete classes.
àWe can persist the one table for Base class and by joining the condition to that Base class table to different tables of all sub classes or Derived class tables called as Table per sub class.
àWe can persist all the class or the whole class hierarchy classes details in one table called as Table per class hierarchy.
That means we can store data in 3-ways while working with Inheritance mapping Model. That means Hibernate supports the three basic inheritance mapping strategies
1.  Table per class hierarchy
2.  Table per concrete class
3.  Table per sub class
àThese 3 are generalized ways of mapping. In addition, Hibernate supports a fourth, slightly different kind of polymorphism.
4.  Implicit polymorphism

1.  Table per class hierarchy:
PAYMENT_HISTORY (TABLE)
PAYMENT_ID
MERCHANT
AMOUNT
CARD_NO
CARD_TYPE
CVV
EXPIRY
CHECH_NO
BANK
EXPIRY
1
BIGBAZR
1000
2
CENTRAL
2000
112122
VISA
122
01-Jan
3
LIFE STYLE
3000
CH1222
SBI
01-Feb

session.get(CardPayment.class,2);
When we get the data from the session then hibernate thinks it is a class which contains all the data details but all the details is not there in the CardPayment hence we should not map this class as normal class in mapping file so we should not map with <class> rather we need to map <subclass> bcz it is sub class of Payment. Hence now hibernate reads the parent class details also from mapping metadata while inserting or retrieving the data. Similarly same for the CheckPayment also.
session.get(Payment.class,2);
It returns the CardPayment bcz of polymorphic Query and id 2 is belongs to CardPayment but hibernate will not identify the whether the data is Payment or CardPayment. Hence in order to differentiate which class obj has been persisted and which class obj is retrieving we need to provide one differentiate column to identify for the hibernate that’s where we need to provide one differentiate column called as discriminator-value column.
PAYMENT_HISTORY (TABLE)
PAYMENT_ID
MERCHANT
AMOUNT
CARD_NO
CARD_TYPE
CVV
EXPIRY
CHECH_NO
BANK
EXPIRY
TYPE
1
BIGBAZR
1000
PAY
2
CENTRAL
2000
112122
VISA
122
01-Jan
CARD
3
LIFE STYLE
3000
CH1222
SBI
01-Feb
CHK

So we need to provide the discriminator column value in Base class hbm file and write the 3-hbm files with <class> tag for base class which is normal class and Derived classes as <subclass> which is incomplete mapping and it is extending the mapping meta data info from the super class.
àConfiguration Approach:
Payment.hbm.xml:
<hibernate-mapping package=>
  <class name=Payment discriminator-value=>
    <id>
      <generator class=>
    </id>
    <discriminator/>
  </class>
</hibernate-mapping>
CardPayment.hbm.xml:
<hibernate-mapping>
  <subclass discriminator-value=>
  </subclass>
</hibernate-mapping>

CheckPayment.hbm.xml:
<hibernate-mapping>
  <subclass>
  </subclass>
</hibernate-mapping>
àAnnotation Driven Approach:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "PAYMENT_TYPE", discriminatorType= DiscriminatorType.STRING)
@DiscriminatorValue(value = "PAYMENT")
@Table(name = "PAYMENT_HISTORY")

Note:
àAnnotations also will inherit from one Annotation to another annotation.

2.  Table per concrete class:
PAYMENT
PAYMENT_ID
MERCHANT

AMOUNT
CARD_PAYMENT
CHEQUE_PAYMENT
PAYMENT_ID
PAYMENT_ID
MERCHANT
MERCHANT
AMOUNT
AMOUNT
CARD_NO
CHECK_NO
CARD_TYPE
BANK
CVV
ISS_DT
EXPIRY

PAYMENT:
PAYMENT_ID
MERCHANT
AMOUNT
1
BIGBAZR
1000

CARD_PAYMENT:
PAYMENT_ID
MERCHANT
AMOUNT
CARD_NO
CARD_TYPE
CVV
EXPIRY
2
CENTRAL
2000
112122
VISA
122
01-Jan

CHEQUE_PAYMENT:
PAYMENT_ID
MERCHANT
AMOUNT
CHECH_NO
BANK
ISS_DT
3
LIFE STYLE
3000
CH1222
SBI
13-11-2015

àIf any change happen in the Payment class that means if any extra attribute added in the Payment class it impact the all the sub classes of its corresponding tables.
PAYMENT
PAYMENT_ID
MERCHANT
AMOUNT

PAYMENT_CHARGE
CARD_PAYMENT
CHEQUE_PAYMENT
PAYMENT_ID
PAYMENT_ID
MERCHANT
MERCHANT
AMOUNT
AMOUNT
CARD_NO
CHECK_NO
CARD_TYPE
BANK
CVV
ISS_DT
EXPIRY

PAYMENT:
PAYMENT_ID
MERCHANT
AMOUNT
PAYMENT_CHARGE
1
BIGBAZR
1000
10
CARD_PAYMENT:
PAYMENT_ID
MERCHANT
AMOUNT
CARD_NO
CARD_TYPE
CVV
EXPIRY
PAYMENT_CHARGE
2
CENTRAL
2000
112122
VISA
122
01-Jan
10
CHEQUE_PAYMENT:
PAYMENT_ID
MERCHANT
AMOUNT
CHECH_NO
BANK
ISS_DT
PAYMENT_CHARGE
3
LIFE STYLE
3000
CH1222
SBI
13-11-2015
10

àsession.get(CardPayment.class,2);
Dieclty goes to the CARD_PAYMENT table and fetches the data based on the id.
àUnion Polymorphic Queries:
session.get(Payment.class,1);àUnion polymorphic query
session.get(Payment.class,2);àUnion polymorphic query
session.get(Payment.class,3);àUnion polymorphic query
àIn Table per class hierarchy based on the id 1st it identifies the record is there or not and then using the discriminator column it will identifies the corresponding class and populates the data into the obj.
àIn Table per concrete class hierarchy when we specify the id as 2 then it will goes to the DB and hibernate tries to combine/union all the tables in a single query (instead of multiple queries) and then tries to identifies in which table id it is existing and then populates the data into the class obj, Hence we need to write <union-subclass> as the tag in each and every derived child class. That means in order to get the data union all the class tables.
Note:
In order to query the data from Table per concrete class Inheritance strategy the id should be unique across the heirachy of tables then only it will identifies corresponding class obj based on the id and by using union of all the class tables.
àUse Case:
For example if we go to the shopping-mall then we pay the payment using payment or card or cheque and assume we pay via Card then we if we go again to the shopping-mall for exchange then they scan the paymentId and based on the paymentId they scanned it needs to fetch the details of CardPayment from their DB but they never enter the card details so in this use case polymorphic queries are use full.
àPayment.hbm.xml:
<hibernate-mapping package="com.tpcc.entities">
  <class name="Payment" table="PAYMENT">
    <id name="paymentId" type="int">
     <column name="PAYMENT_ID" />
       <generator class="increment" />
    </id>
           <property name="merchant" type="string">
                <column name="MERCHANT" />
           </property>
           <property name="amount" type="float">
                <column name="AMOUNT" />
           </property>
  </class>
</hibernate-mapping>            

àCardPayment.hbm.xml

<hibernate-mapping package="com.tpcc.entities">
   <union-subclass name="CardPayment" extends="Payment"
           table="CARD_PAYMENT">
   </union-subclass>
</hibernate-mapping>            

àChequePayment.hbm.xml
<hibernate-mapping package="com.tpcc.entities">
   <union-subclass name="ChequePayment" extends="Payment"
           table="CHEQUE_PAYMENT">
   </union-subclass>
</hibernate-mapping>            

àAnnotation Driven Approach:
@Table(name = "PAYMENT")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@AttributeOverrides({
@AttributeOverride(name = "paymentId", column = @Column(name = "CRD_PAYMENT_ID")),
@AttributeOverride(name = "merchant", column = @Column(name = "CRD_MERCHANT")),
@AttributeOverride(name = "AMOUNT", column = @Column(name = "CRD_AMOUNT")) })
@Id
@GeneratedValue(generator = "hib-generator")//jpa
//hibernate
@GenericGenerator(name = "hib-generator", strategy = "increment") @Column(name = "PAYMENT_ID")

3.  Table per sub class:
àIn Table per class heirachy column names are duplicated across all the sub class tables. So to avoid the duplication of columns in all the sub class tables we are going for Table per subclass.

PAYMENT:

PAYMENT_ID


MERCHANT


AMOUNT
1
BIGBAZR
1000
2
LIFE STYLE
2000
3
PANTALOONS
3000

CARD_PAYMENT:
CARD_PAYMENT_ID
CARD_NO
CARD_TYPE
CVV
EXPIRY
2
112122
VISA
122
01-Jan

CHEQUE_PAYMENT:
CHEQUE_PAYMENT_ID
CHECH_NO
BANK
ISS_DT

3
CH1222
SBI
13-11-15

àsession.get(CardPayment.class,2);
When we tries to fetch the data hibernate will not get the CardPayment details unless until we have join relation with CardPayment and Payment that’s why we need to provide the PK of PAYMENT table as join column to CardPayment called as key-column which makes the joining of 2-tables while getting the data.
àWhen we call session.get(CardPayment.class,2); then hibernate will goes to the CardPayment and makes join query with Payment as equi-join bcz we are directly specifying the CardPayment and gets the data.

àIf session.get(Payment.class,2); then hibernate will makes polymorphic query against all the classes and makes the left-outer join with super class table and all the tables of sub classes bcz we specified Payment.class which will tries to identifies the corresponding class obj based on the join condition with all the tables and their key-column (PK of Payment as FK in all sub classes) then gives the data. So it tries to get the data by joining the super class table with sub class table hence we need to specify the tag <join-subclass> in all the sub class mapping files.
Left outer join means always Payment details and either CardPayment or ChequePayment.
Payment.hbm.xml
<hibernate-mapping package="com.tpsc.entities">
  <class name="Payment" table="PAYMENT">
    <id name="paymentId" type="int">
      <column name="PAYMENT_ID" />
         <generator class="increment" />
    </id
  </class>
</hibernate-mapping>
CardPayment.hbm.xml:
<hibernate-mapping package="com.tpsc.entities">
  <joined-subclass name="CardPayment" extends="Payment"
table="CARD_PAYMENT">
     <key column="CRD_PAYMENT_ID" />
  </joined-subclass>
</hibernate-mapping>
ChequePayment.hbm.xml:
<hibernate-mapping package="com.tpsc.entities">
   <joined-subclass name="ChequePayment" extends="Payment"
     table="CHEQUE_PAYMENT">
     <key column="CHQ_PAYMENT_ID" />
   </joined-subclass>
</hibernate-mapping>

àAnnotation Driven Approach:
@Entity
@Table(name = "PAYMENT")
@Inheritance(strategy = InheritanceType.JOINED)
@Entity
@Table(name = "CARD_PAYMENT")
@PrimaryKeyJoinColumn(name = "CRD_PAYMENT_ID")


4.  Implicit polymorphism:
àIt is specific to hibernate it not a general ORM based mapping model.
àIn this approach individual tables will be created for super class and it’s for each and every sub class.
àThere is no relation with one mapping file with another mapping and while persisting hibernate will identifies based on the inheritance relation between the classes.

Comments

Popular posts from this blog

Mockito interview Questions

1.       Question 1. What Is Mockito? Answer : Mockito allows creation of mock object for the purpose of Test Driven Development and Behavior Driven development. Unlike creating actual object, Mockito allows creation of fake object (external dependencies) which allows it to give consistent results to a given invocation. 2.       Question 2. Why Do We Need Mockito? What Are The Advantages? Answer : Mockito differentiates itself from the other testing framework by removing the expectation beforehand. So, by doing this, it reduces the coupling. Most of the testing framework works on the "expect-run-verify". Mockito allows it to make it "run-verify" framework. Mockito also provides annotation which allows to reduce the boilerplate code. 3.       Question 3. Can You Explain A Mockito Framework? Answer : In Mockito, you always check a particular class. The dependency in that class is injected using m...

JAVA Expert Interview Questions Answers 2017

Java Basics ::  Interview Questions and Answers Home  »  Interview Questions  »  Technical Interview  »  Java Basics  » Interview Questions 1.     What is the difference between a constructor and a method? A constructor is a member function of a class that is used to create objects of that class. It has the same name as the class itself, has no return type, and is invoked using the new operator. A method is an ordinary member function of a class. It has its own name, a return type (which may be void), and is invoked using the dot operator. 2.     What is the purpose of garbage collection in Java, and when is it used? The purpose of garbage collection is to identify and discard objects that are no longer needed by a program so that their resources can be reclaimed and reused. A Java object is subject to garbage collection when it becomes unreachable to the program in which it is used. 3.  ...

Java Example Program to Convert List to Set

import java.util.ArrayList; import java.util.HashSet; import java.util.Set; public class ListToSet {  /**   * @author Amarjit Kumar   * @category interview questions   *   * Description: Convert List to set in java with example program   *   */  public static void main(String[] args) {   ArrayList<String> arrList= new ArrayList<>();   arrList.add("Java");   arrList.add("Java");   arrList.add("List to String");   arrList.add("Example Program");   Set<String> strSet = new HashSet<String>(arrList);   System.out.println(strSet);   System.out.println(arrList);  } } /*  * Java program to convert list to set. Convert ArrayList of string to HashSet  * in java example program How to convert List to Set in java Set<String> strSet  * = new HashSet<String>(arrList); HashSet having a constructor which will take  * list as an ar...