Showing posts with label Inheritance Mapping. Show all posts
Showing posts with label Inheritance Mapping. Show all posts

May 7, 2011

Hibernate Inheritance Mapping (Strategy 4) - Table per subclass

In strategy-4, each persistent class in the inheritance hierarchy, whether concrete or abstract, is mapped to a table each in the Database schema. The inheritance relationship between the domain classes is reflected in the mapping files through special XML elements and in the Database schema as relationship foreign-key associations between the tables.

1) Create the persistent classes inheritance hierarchy with S4 as the superclass and A4 and B4 as the subclasses that extend from the superclass.

S4.java

package info.icontraining.hibernate;

public abstract class S4 {

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


A4.java

package info.icontraining.hibernate;

public class A4 extends S4 {

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


B4.java

package info.icontraining.hibernate;

public class B4 extends S4 {

   private String p5;
   private String p6;
 
   public B4() { }
 
   public B4(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, AB4.hbm.xml,

AB4.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.S4" table="S4_TABLE" > 
      <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" />
      <joined-subclass name="info.icontraining.hibernate.A4" table="A4_TABLE">
         <key column="A4_ID"/>
         <property name="p3" column="P3" type="string" />
         <property name="p4" column="P4" type="string" />
      </joined-subclass>
      <joined-subclass name="info.icontraining.hibernate.B4" table="B4_TABLE">
         <key column="B4_ID" />
         <property name="p5" column="P5" type="string" />
         <property name="p6" column="P6" type="string" />
      </joined-subclass>
   </class> 
</hibernate-mapping>


3) In the hibernate.cfg.xml file, add the following configuration,
<mapping resource="info/icontraining/hibernate/AB4.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 InheritanceDemo4 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(); 
      A4 a1 = new A4("str1", "str2", "str3", "str4");
      B4 b1 = new B4("str1", "str2", "str5", "str6");
      session.save(a1); 
      session.save(b1);
      tx.commit(); 
      session.close(); 

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


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

<servlet>
   <servlet-name>InheritanceDemo4</servlet-name>
   <servlet-class>info.icontraining.servlets.InheritanceDemo4</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>InheritanceDemo4</servlet-name>
   <url-pattern>/inheritanceDemo4</url-pattern>
</servlet-mapping>


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

http://localhost:8080/WebAppName/inheritanceDemo4

Hibernate Inheritance Mapping (Strategy 3) - Table per inheritance hierarchy

In strategy-3, the entire inheritance hierarchy is mapped to a single table in the Database Schema. The mapping file reflects the existence of inheritance through special elements in the XML.

1) Create the persistent classes inheritance hierarchy, S3 is the superclass and A3 and B3 are the subclasses that inherit from the superclass.

S3.java

package info.icontraining.hibernate;

public class S3 {

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

A3.java

package info.icontraining.hibernate;

public class A3 extends S3 {

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

B3.java

package info.icontraining.hibernate;

public class B3 extends S3 {

   private String p5;
   private String p6;
 
   public B3() { }
 
   public B3(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, AB3.hbm.xml

AB3.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.S3" table="SAB3_TABLE" > 
      <id name="id" column="ID" type="long" > 
         <generator class="native" /> 
      </id>
      <discriminator column="DISC_COL" type="string" />
      <property name="p1" column="P1" type="string" />
      <property name="p2" column="P2" type="string" />
      <subclass name="info.icontraining.hibernate.A3" discriminator-value="a3">
         <property name="p3" column="P3" type="string" />
         <property name="p4" column="P4" type="string" />
      </subclass>
      <subclass name="info.icontraining.hibernate.B3" discriminator-value="b3">
         <property name="p5" column="P5" type="string" />
         <property name="p6" column="P6" type="string" />
      </subclass>
   </class> 
</hibernate-mapping> 


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

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

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


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

<servlet>
   <servlet-name>InheritanceDemo3</servlet-name>
   <servlet-class>info.icontraining.servlets.InheritanceDemo3</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>InheritanceDemo3</servlet-name>
   <url-pattern>/inheritanceDemo3</url-pattern>
</servlet-mapping>


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

http://localhost:8080/WebAppName/inheritanceDemo3

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

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