Sponsored Links
Ad by Google
In my previous post we have seen Table Per Concrete Class Inheritance Hierarchy Example Using Annotation. In this post we are going to see the implementation of Table Per Sub Class hierarchy mapping using annotation. Hibernate supports three basic inheritance mapping strategies
Below are the tables ER diagram we are using for this tutorial.
In this project we are using four classes, three sub class and one super class and those are listed here in diagram
Payment.java is our Super class and three different sub classes are-
Main Objects of this project are:
Overview of the Project Structure:
Step 1. Create database script.
Step 2. Create a Maven Project:
Step A: Go to File->New->Other..
Step B: Select Maven Project from the select wizard.
Step C: Select project name and location from New Maven Project wizard.
Step D: Configure project provide GroupId, artifactId etc. See the details from the screenshot. This screen shot is from our previous post so here you need to change the artifact Id something like Table-Per-Sub-Class-Annotation and project name also as Table-Per-Sub-Class-Annotation.
Step E: After completion of all the above steps, now your project will looks like this screenshot.
3. Add project dependencies into pom.xml file:
Double click on your project's pom.xml file, it will looks like this with very limited information.
Now add Hibernate and MySql dependencies entry inside pom.xml file. Paste the below code inside the project tag of pom.xml file.
Here is a complete pom.xml file
Step 4. Create a hibernate.cfg.xml file: Here we placed hibernate.cfg.xml file inside src/main/resources.
hibernate.cfg.xml
Step 5: Create Payment.java entity class:
Note: We are using inheritance type joined, using @Inheritance(strategy = InheritanceType.JOINED) for table per sub class inheritance.
Step 6: Now create CardPayment.java sub class
Note: We are using here @PrimaryKeyJoinColumn(name = "payment_id") to make the association of one to one with super class(Payment.java).
Step 7: Create another sub class ChequePayment.java
Step 8: Create another sub class CashPayment.java
Step 9: Create HibernateUtility.java class to build sessionFactory via loading configuration file.
Step 10: Create PaymentDAO.java class to perform CRUD operations,
Step 11: Create PaymentService.java class to call the methods of DAO class.
PaymentService.java
Note: Before inserting record into sub class it will insert row inside super class and place the super class id into sub class.
Run the PaymentService.java class it will generate two insert query one for super class(payment ) and one for sub class(cardpayment)
OUT PUT:
That's it
Download the complete example from here Source Code
References
Reference 1
Reference 2
- table per class hierarchy (using annotation)
- table per concrete class (using XML)
- table per sub class
Below are the tables ER diagram we are using for this tutorial.
In this project we are using four classes, three sub class and one super class and those are listed here in diagram
Payment.java is our Super class and three different sub classes are-
- CardPayment.java
- ChequePayment.java
- CashPayment.java
Tools and Technologies we are using here:
- JDK 7
- Hibernate 4.3.7
- MySql 5.1.10
- Eclipse Juno 4.2
- Maven 3.2
Main Objects of this project are:
- pom.xml
- hibernate.cfg.xml
- annotated pojo
- database
Overview of the Project Structure:
Step 1. Create database script.
CREATE DATABASE `hibernate_tutorial`; USE `hibernate_tutorial`; DROP TABLE IF EXISTS `cardpayment`; CREATE TABLE `cardpayment` ( `payment_id` bigint(20) NOT NULL, `card_type` varchar(255) DEFAULT NULL, PRIMARY KEY (`payment_id`), CONSTRAINT `FK_7lj2yejd6xxafp2gxmca7ydc0` FOREIGN KEY (`payment_id`) REFERENCES `payment` (`payment_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*Table structure for table `cashpayment` */ DROP TABLE IF EXISTS `cashpayment`; CREATE TABLE `cashpayment` ( `payment_id` bigint(20) NOT NULL, PRIMARY KEY (`payment_id`), CONSTRAINT `FK_tim1eyc54hq37ev6488imimmf` FOREIGN KEY (`payment_id`) REFERENCES `payment` (`payment_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*Table structure for table `chequepayment` */ DROP TABLE IF EXISTS `chequepayment`; CREATE TABLE `chequepayment` ( `payment_id` bigint(20) NOT NULL, `bank` varchar(255) DEFAULT NULL, PRIMARY KEY (`payment_id`), CONSTRAINT `FK_l59sf4vy46sgqqpaf1u0ticlw` FOREIGN KEY (`payment_id`) REFERENCES `payment` (`payment_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*Table structure for table `payment` */ DROP TABLE IF EXISTS `payment`; CREATE TABLE `payment` ( `payment_id` bigint(20) NOT NULL AUTO_INCREMENT, `amount` float DEFAULT NULL, `order_number` varchar(255) DEFAULT NULL, `payment_date` datetime DEFAULT NULL, PRIMARY KEY (`payment_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Step 2. Create a Maven Project:
Step A: Go to File->New->Other..
Step B: Select Maven Project from the select wizard.
Step C: Select project name and location from New Maven Project wizard.
Step D: Configure project provide GroupId, artifactId etc. See the details from the screenshot. This screen shot is from our previous post so here you need to change the artifact Id something like Table-Per-Sub-Class-Annotation and project name also as Table-Per-Sub-Class-Annotation.
Step E: After completion of all the above steps, now your project will looks like this screenshot.
3. Add project dependencies into pom.xml file:
Double click on your project's pom.xml file, it will looks like this with very limited information.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javamakeuse.inheritance</groupId> <artifactId>Table-Per-Sub-Class-Annotation</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Table-Per-Sub-Class-Annotation</name> </project>
Now add Hibernate and MySql dependencies entry inside pom.xml file. Paste the below code inside the project tag of pom.xml file.
<dependencies> <!-- Hibernate Dependency --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.7.Final</version> </dependency> <!-- MySql Connector dependency --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.10</version> </dependency> </dependencies>
Here is a complete pom.xml file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javamakeuse.inheritance</groupId> <artifactId>Table-Per-Sub-Class-Annotation</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Table-Per-Sub-Class-Annotation</name> <dependencies> <!-- Hibernate Dependency --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.7.Final</version> </dependency> <!-- MySql Connector dependency --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.10</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
Step 4. Create a hibernate.cfg.xml file: Here we placed hibernate.cfg.xml file inside src/main/resources.
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate_tutorial</property> <property name="connection.username">root</property> <property name="connection.password">root123</property> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping class="com.javamakeuse.inheritance.pojo.Payment"/> <mapping class="com.javamakeuse.inheritance.pojo.CardPayment"/> <mapping class="com.javamakeuse.inheritance.pojo.ChequePayment"/> <mapping class="com.javamakeuse.inheritance.pojo.CashPayment"/> </session-factory> </hibernate-configuration>
Step 5: Create Payment.java entity class:
package com.javamakeuse.inheritance.pojo; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity @Table(name = "payment") @Inheritance(strategy = InheritanceType.JOINED) public class Payment { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "payment_id") private long paymentID; @Column(name = "amount") private float amount; @Column(name = "order_number") private String orderNumber; @Column(name = "payment_date") @Temporal(TemporalType.DATE) private Date paymentDate; public long getPaymentID() { return paymentID; } public void setPaymentID(long paymentID) { this.paymentID = paymentID; } public float getAmount() { return amount; } public void setAmount(float amount) { this.amount = amount; } public String getOrderNumber() { return orderNumber; } public void setOrderNumber(String orderNumber) { this.orderNumber = orderNumber; } public Date getPaymentDate() { return paymentDate; } public void setPaymentDate(Date paymentDate) { this.paymentDate = paymentDate; } @Override public String toString() { return "Payment [amount=" + amount + ", orderNumber=" + orderNumber + ", paymentDate=" + paymentDate + "]"; } }
Note: We are using inheritance type joined, using @Inheritance(strategy = InheritanceType.JOINED) for table per sub class inheritance.
Step 6: Now create CardPayment.java sub class
package com.javamakeuse.inheritance.pojo; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table(name = "card_payment") @PrimaryKeyJoinColumn(name = "payment_id") public class CardPayment extends Payment { @Column(name = "card_type") private String cardType; public String getCardType() { return cardType; } public void setCardType(String cardType) { this.cardType = cardType; } @Override public String toString() { return "CardPayment [cardType=" + cardType + "]"; } }
Note: We are using here @PrimaryKeyJoinColumn(name = "payment_id") to make the association of one to one with super class(Payment.java).
Step 7: Create another sub class ChequePayment.java
package com.javamakeuse.inheritance.pojo; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table(name = "cheque_payment") @PrimaryKeyJoinColumn(name = "payment_id") public class ChequePayment extends Payment { @Column(name = "bank") private String bank; public String getBank() { return bank; } public void setBank(String bank) { this.bank = bank; } @Override public String toString() { return "ChequePayment [bank=" + bank + "]"; } }
Step 8: Create another sub class CashPayment.java
package com.javamakeuse.inheritance.pojo; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table(name = "cash_payment") @PrimaryKeyJoinColumn(name = "payment_id") public class CashPayment extends Payment { }
Step 9: Create HibernateUtility.java class to build sessionFactory via loading configuration file.
package com.javamakeuse.inheritance.util; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; public class HibernateUtility { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { Configuration configuration = new Configuration(); configuration.configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()).build(); SessionFactory sessionFactory = configuration .buildSessionFactory(serviceRegistry); return sessionFactory; } public static SessionFactory getSessionFactory() { return sessionFactory; } }
Step 10: Create PaymentDAO.java class to perform CRUD operations,
package com.javamakeuse.inheritance.dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import com.javamakeuse.inheritance.pojo.Payment; import com.javamakeuse.inheritance.util.HibernateUtility; public class PaymentDAO { static SessionFactory sessionFactory; static { sessionFactory = HibernateUtility.getSessionFactory(); } public static Payment save(Payment payment) { Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(payment); session.getTransaction().commit(); return payment; } public static Payment update(Payment payment) { Session session = sessionFactory.openSession(); session.beginTransaction(); session.merge(payment); session.getTransaction().commit(); return payment; } public static void delete(Payment payment) { Session session = sessionFactory.openSession(); session.beginTransaction(); session.delete(payment); session.getTransaction().commit(); } }
Step 11: Create PaymentService.java class to call the methods of DAO class.
PaymentService.java
package com.javamakeuse.hbm.inheritance.service; import java.text.SimpleDateFormat; import com.javamakeuse.hbm.inheritance.dao.PaymentDAO; import com.javamakeuse.hbm.inheritance.pojo.CardPayment; public class PaymentService { public static void main(String[] args) { try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // using CardPayment CardPayment payment = new CardPayment(); payment.setCardType("Debit"); payment.setAmount(250); payment.setOrderNumber("WO0001"); payment.setPaymentDate(sdf.parse("2015-01-01")); // using ChequePayment /* * ChequePayment payment = new ChequePayment(); * payment.setBank("SBI"); */ // using CashPayment /* * CashPayment payment = new CashPayment(); payment.setAmount(250); */ PaymentDAO.save(payment); } catch (Exception e) { e.printStackTrace(); } } }
Note: Before inserting record into sub class it will insert row inside super class and place the super class id into sub class.
Run the PaymentService.java class it will generate two insert query one for super class(payment ) and one for sub class(cardpayment)
OUT PUT:
Hibernate: insert into payment (amount, order_number, payment_date) values (?, ?, ?) Hibernate: insert into cardpayment (card_type, payment_id) values (?, ?)
payment table:
cardpayment table:
That's it
Download the complete example from here Source Code
References
Reference 1
Reference 2
Sponsored Links
0 comments:
Post a Comment