May 7, 2011

Hibernate Inheritance Mapping (Strategy 1) - Table per concrete class with implicit polymorphism

In strategy-1, we map only the concrete persistent classes in the inheritance hierarchy to a table each in the Database Schema. The abstract classes are not mapped. Neither the mapping files nor the Database schema reflect that inheritance exists in the domain classes, making it implicit polymorphism.

1) Create the 3 persistent classes, where the super class, S, is an abstract class and the two sub-classes that extend from the superclass, A and B, are concrete classes.

S.java

package info.icontraining.hibernate;

public abstract class S {

   private Long id;
   private String p1;
   private String p2;
 
   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   } 
   public String getP1() {
      return p1;
   }
   public void setP1(String p1) {
      this.p1 = p1;
   }
   public String getP2() {
      return p2;
   }
   public void setP2(String p2) {
      this.p2 = p2;
   }
}

A.java

package info.icontraining.hibernate;

public class A extends S {

   private String p3;
   private String p4;
 
   public A() { }
 
   public A(String p1, String p2, String p3, String p4) {
      this.setP1(p1);
      this.setP2(p2);
      this.setP3(p3);
      this.setP4(p4);
   }
 
   public String getP3() {
      return p3;
   }
   public void setP3(String p3) {
      this.p3 = p3;
   }
   public String getP4() {
      return p4;
   }
   public void setP4(String p4) {
      this.p4 = p4;
   }
}

B.java

package info.icontraining.hibernate;

public class B extends S {

   private String p5;
   private String p6;
 
   public B() { }
 
   public B(String p1, String p2, String p5, String p6) {
      this.setP1(p1);
      this.setP2(p2);
      this.setP5(p5);
      this.setP6(p6);
   }
 
   public String getP5() {
      return p5;
   }
   public void setP5(String p5) {
      this.p5 = p5;
   }
   public String getP6() {
      return p6;
   }
   public void setP6(String p6) {
      this.p6 = p6;
   }
}


2) The 2 mapping files for the concrete classes, A and B, will be mapped normally.

A.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
   <class name="info.icontraining.hibernate.A" table="A1"> 
      <id name="id" column="ID"> 
         <generator class="native" /> 
      </id> 
      <property name="p1" column="P1" type="string" />
      <property name="p2" column="P2" type="string" />
      <property name="p3" column="P3" type="string" />
      <property name="p4" column="P4" type="string" />  
   </class> 
</hibernate-mapping>


B.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
   <class name="info.icontraining.hibernate.B" table="B1"> 
      <id name="id" column="ID"> 
         <generator class="native" /> 
      </id> 
      <property name="p1" column="P1" type="string" />
      <property name="p2" column="P2" type="string" />
      <property name="p5" column="P5" type="string" />
      <property name="p6" column="P6" type="string" />  
   </class> 
</hibernate-mapping> 


3) In the hibernate.cfg.xml file, add the following configuration,

<mapping resource="info/icontraining/hibernate/A1.hbm.xml" /> 
<mapping resource="info/icontraining/hibernate/B1.hbm.xml" /> 


4) Create the client code, in a servlet class, as follows,

package info.icontraining.servlets;

import java.io.*; 
import java.util.*; 
import javax.servlet.*; 
import javax.servlet.http.* ; 
import org.hibernate.*; 
import info.icontraining.hibernate.*;

public class InheritanceDemo1 extends HttpServlet { 
  
   public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { 
  
      PrintWriter out = res.getWriter(); 

      Session session = HibernateUtil.getSessionFactory().openSession(); 
      Transaction tx = session.beginTransaction(); 
      A a1 = new A("str1", "str2", "str3", "str4");
      B b1 = new B("str1", "str2", "str5", "str6");
      session.save(a1); 
      session.save(b1);
      tx.commit(); 
      session.close(); 

      Session newSession = HibernateUtil.getSessionFactory().openSession(); 
      Transaction newTransaction = newSession.beginTransaction(); 
      List<A> a = newSession.createQuery("from A").list(); 
      out.println( a.size() + " items found:" ); 
      for ( Iterator<A> iter = a.iterator(); iter.hasNext(); ) { 
         A a2 = iter.next(); 
         out.println( a2.getP1() ); 
      } 
   
      out.println();
      out.println();
   
      List<B> b = newSession.createQuery("from B").list(); 
      out.println( b.size() + " items found:" ); 
      for ( Iterator<B> iter = b.iterator(); iter.hasNext(); ) { 
         B b2 = iter.next(); 
         out.println( b2.getP2() ); 
      } 
   
      newTransaction.commit(); 
      newSession.close(); 
   } 
}


5) Configure the servlet in the web.xml file,

<servlet>
   <servlet-name>InheritanceDemo1</servlet-name>
   <servlet-class>info.icontraining.servlets.InheritanceDemo1</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>InheritanceDemo1</servlet-name>
   <url-pattern>/inheritanceDemo1</url-pattern>
</servlet-mapping>

6) Enter the following URL in the browser to test,

http://localhost:8080/WebAppName/inheritanceDemo1

No comments:

Post a Comment