May 7, 2011

Hibernate Inheritance Mapping (Strategy 2) - Table per concrete class with unions

In strategy-2, the concrete persistent classes in the inheritance hierarchy are mapped to a table each in the Database schema. The abstract classes are not mapped. The mapping file reflects the inheritance in the domain classes by using explicit elements in the XML.

1) Create the 3 persistent classes, S2.java is the abstract superclass, and A2 and B2 are concrete subclasses that extend from the superclass.

S2.java

package info.icontraining.hibernate;

public abstract class S2 {

   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;
   } 
}

A2.java

package info.icontraining.hibernate;

public class A2 extends S2 {

   private String p3;
   private String p4;
 
   public A2() { }
 
   public A2(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;
   } 
}


B2.java

package info.icontraining.hibernate;

public class B2 extends S2 {

   private String p5;
   private String p6;
 
   public B2() { }
 
   public B2(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) Create the mapping file AB2.xml,

AB2.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.S2" abstract="true" > 
      <id name="id" column="ID" type="long" > 
         <generator class="native" /> 
      </id> 
      <property name="p1" column="P1" type="string" />
      <property name="p2" column="P2" type="string" />
      <union-subclass name="info.icontraining.hibernate.A2" table="A2_TABLE">
         <property name="p3" column="P3" type="string" />
         <property name="p4" column="P4" type="string" />
      </union-subclass>
      <union-subclass name="info.icontraining.hibernate.B2" table="B2_TABLE">
         <property name="p5" column="P5" type="string" />
         <property name="p6" column="P6" type="string" />
      </union-subclass>
   </class> 
</hibernate-mapping>


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

<mapping resource="info/icontraining/hibernate/AB2.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 InheritanceDemo2 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(); 
      A2 a1 = new A2("str1", "str2", "str3", "str4");
      B2 b1 = new B2("str1", "str2", "str5", "str6");
      session.save(a1); 
      session.save(b1);
      tx.commit(); 
      session.close(); 

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


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

<servlet>
   <servlet-name>InheritanceDemo2</servlet-name>
   <servlet-class>info.icontraining.servlets.InheritanceDemo2</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>InheritanceDemo2</servlet-name>
   <url-pattern>/inheritanceDemo2</url-pattern>
</servlet-mapping>


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

http://localhost:8080/WebAppName/inheritanceDemo2

No comments:

Post a Comment