Let’s
write a simple application using inheritance and see how hibernate handles
inheritance. In later posts we see how to tweak default inheritance strategy
handled by Hibernate.
Let’s
say I had a product class and all the products like Books, laptops, cameras
etc. all implements Product class like below.
package myFirstHibernate; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Product { @Id @GeneratedValue int id; private int noOfProducts; public int getNoOfProducts() { return noOfProducts; } public void setNoOfProducts(int noOfProducts) { this.noOfProducts = noOfProducts; } }
package myFirstHibernate; import javax.persistence.Entity; @Entity public class Book extends Product{ private String title; private String author; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } }
package myFirstHibernate; import javax.persistence.Entity; @Entity public class Laptop extends Product { private String brand; private String model; public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } }
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database Connection settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/sample</property> <property name="connection.username">root</property> <property name="connection.password">tiger</property> <!-- Enable the logging of all the generated SQL statements to the console --> <property name="show_sql">true</property> <!-- Format the generated SQL statement to make it more readable, --> <property name="format_sql">false</property> <!-- Hibernate will put comments inside all generated SQL statements to hint what’s the generated SQL trying to do --> <property name="use_sql_comments">false</property> <!-- This property makes Hibernate generate the appropriate SQL for the chosen database. --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> <!-- mappings for annotated classes --> <mapping class="myFirstHibernate.Product" /> <mapping class="myFirstHibernate.Book" /> <mapping class="myFirstHibernate.Laptop" /> </session-factory> </hibernate-configuration>
package myFirstHibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class TestInheritance { /* Step 1: Create session factory */ private static SessionFactory getSessionFactory() { Configuration configuration = new Configuration().configure(); StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder(). applySettings(configuration.getProperties()); SessionFactory factory = configuration.buildSessionFactory(builder.build()); return factory; } public static void main(String args[]){ Product prod = new Product(); Book book = new Book(); Laptop laptop = new Laptop(); prod.setNoOfProducts(2234); book.setAuthor("eckhart tolle"); book.setNoOfProducts(1234); book.setTitle("The Power of Now"); laptop.setBrand("Dell"); laptop.setModel("Alienware 17 Laptop"); laptop.setNoOfProducts(1000); /* To persist data */ SessionFactory sessionFactory = getSessionFactory(); Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(prod); session.save(book); session.save(laptop); session.getTransaction().commit(); session.close(); } }
Run
TestInheritance class, you will get output like below.
Hibernate: drop table if exists Product Hibernate: create table Product (DTYPE varchar(31) not null, id integer not null auto_increment, noOfProducts integer not null, author varchar(255), title varchar(255), brand varchar(255), model varchar(255), primary key (id)) Dec 22, 2014 10:20:48 AM org.hibernate.tool.hbm2ddl.SchemaExport execute INFO: HHH000230: Schema export complete Hibernate: insert into Product (noOfProducts, DTYPE) values (?, 'Product') Hibernate: insert into Product (noOfProducts, author, title, DTYPE) values (?, ?, ?, 'Book') Hibernate: insert into Product (noOfProducts, brand, model, DTYPE) values (?, ?, ?, 'Laptop')
MySQL
table structure looks like below.
mysql> describe product; +--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+ | DTYPE | varchar(31) | NO | | NULL | | | id | int(11) | NO | PRI | NULL | auto_increment | | noOfProducts | int(11) | NO | | NULL | | | author | varchar(255) | YES | | NULL | | | title | varchar(255) | YES | | NULL | | | brand | varchar(255) | YES | | NULL | | | model | varchar(255) | YES | | NULL | | +--------------+--------------+------+-----+---------+----------------+ 7 rows in set (0.04 sec) mysql> select * from product; +---------+----+--------------+---------------+------------------+-------+---------------------+ | DTYPE | id | noOfProducts | author | title | brand | model | +---------+----+--------------+---------------+------------------+-------+---------------------+ | Product | 1 | 2234 | NULL | NULL | NULL | NULL | | Book | 2 | 1234 | eckhart tolle | The Power of Now | NULL | NULL | | Laptop | 3 | 1000 | NULL | NULL | Dell | Alienware 17 Laptop | +---------+----+--------------+---------------+------------------+-------+---------------------+ 3 rows in set (0.00 sec)
As
you observe above, There is only one table created for all the three classes
Product, Book, Laptop. This is called Single table strategy of hibernate
inheritance. This is the default strategy of hibernate inheritance.
In
single table strategy, all the field names of classes and sub classes are
becomes columns names of the table. In addition to this, you can see one more
column “DTYPE” (stands for Discriminator column) is added to product table, it
specifies, this row belongs to particular class.
“DTYPE”
= “Product” specifies this row is of type class Product.
“DTYPE”
= “Book” specifies this row is of type class Book.
“DTYPE”
= “Laptop” specifies this row is of type class Laptop.
No comments:
Post a Comment