Newsletter |
Hibernate Inheritance: Table Per Class Hierarchy
Here is the explanation and one example on hibernate table per class hierarchy, consider we have base class named Payment and 2 derived classes like CreditCard, Cheque
If we save the derived class object like CreditCard or Cheque then automatically Payment class object will also be saved into the database, and in the database all the data will be stored into a single table only, which is base class table for sure.
But here we must use one extra discriminator column in the database, just to identify which derived class object we have been saved in the table along with the base class object, if we are not using this column hibernate will throws the exception, see this example so that you will get one idea on this concept.
Required files_
- Payment.java (Base class)
- CreditCard.java (Derived class)
- Cheque.java (Derived class)
- ClientForSave.java (for our logic)
- Payment.hbm.xml
- hibernate.cfg.xml
Payment.java:
package str; public class Payment{ private int paymentId; private double amount; public int getPaymentId() { return paymentId; } public void setPaymentId(int paymentId) { this.paymentId = paymentId; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } }
CreditCard.java:
package str; public class CreditCard extends Payment{ private String CreditCardType; public String getCreditCardType() { return CreditCardType; } public void setCreditCardType(String creditCardType) { CreditCardType = creditCardType; } }
Cheque.java:
package str; public class Cheque extends Payment{ private String ChequeType; public String getChequeType() { return ChequeType; } public void setChequeType(String chequeType) { ChequeType = chequeType; } }
ClientForSave.java
package str; import org.hibernate.*; import org.hibernate.cfg.*; public class ClientForSave { public static void main(String[] args) { Configuration cfg = new Configuration(); cfg.configure("hibernate.cfg.xml"); SessionFactory factory = cfg.buildSessionFactory(); Session session = factory.openSession(); CreditCard c=new CreditCard(); c.setPaymentId(10); c.setAmount(2500); c.setCreditCardType("Visa"); Cheque c1=new Cheque(); c1.setPaymentId(11); c1.setAmount(2600); c1.setChequeType("ICICI"); Transaction tx = session.beginTransaction(); session.save(c); session.save(c1); System.out.println("Object saved successfully.....!!"); tx.commit(); session.close(); factory.close(); } }
Payment.hbm.xml:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="str.Payment" table="PAYMENT"> <id name="paymentId" column="pid" /> <discriminator column="dcolumn" type="string" length="5"/> <property name="amount" column="amt" /> <subclass name="str.CreditCard" discriminator-value="CC"> <property name="CreditCardType" column="cctype" length="10" /> </subclass> <subclass name="str.Cheque" discriminator-value="cq"> <property name="ChequeType" column="cqtype" length="10" /> </subclass> </class> </hibernate-mapping>
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">oracle.jdbc.driver.OracleDriver </property> <property name="connection.url">jdbc:oracle:thin:@www.java4s.com:1521:XE</property> <property name="connection.username">system</property> <property name="connection.password">admin</property> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping resource="Payment.hbm.xml" /> </session-factory> </hibernate-configuration>
Eclipse Output
In the database
Notes:
- Payment.java, CreditCard.java, Cheque.java are just pojo classes nothing to explain, but see in CreditCard.java, Cheque.java i have inherited the Payment.java.
- In this inheritance concept, mapping file is the central part, see in line number 10, we added one new line discriminator, after the id element just to identify which derived class object we have been saved in the table (see the oracle console once)
- every thing has been saved in a single table
You Might Also Like
::. About the Author .:: | ||
Hello Java4s,
I have a doubt in these lines 10,13, 17 of Payment.hbm.xml.
1. Why we have used discriminator-value as an attribute to the element?
2. Can we take discriminator-value as a separate element? If yes/not why?
Hello java4s,
In real time scenarios, where we can use this concept?
Just give a hint to analyze utilization of this concept.
Big thanks to Java4s,but i have a little confusion over the table columns.i have 2 queries.
1)can u give the query for the table(How many columns it has we need to create the discriminator column here or not)?
2)when we will use table per class in our App dev ?
Please give me the reply asap.
regards,
siva
Hi, Java4s
I think you might be aware but still i am just intimating you buddy that in all these three INHERITANCE base examples you have missed out to show ClientForSave.java files details.
One solution is user can download the code and read the ClientForSave.java.
But as all other examples includes all the required files so i just think i should let you know.
Thanks
RajKirpal
@RajKirpal
Thanks dude, really am shocked.
Not sure why my friends missed this, i think they might given the reason in previous articles i guess.
Any way our team realized this 🙂 really appreciate you(r) valuable time to inform us.
We will update ASAP.
Thank you so much RajKirpal.
Hello Java4s Team,
I understand all the programs of Hibernate Inheritance concepts but am getting Confusion in the topic names
In my understanding:
Table per class hierarchy means – one table for one class hierarchy.
Table per subclass hierarchy – one table for one subclass.
Table per concrete class hierarchy – one table for one concrete class. Here I did not understand meaning of concrete.
Please explain in precise terms for easy understanding.
Thanks
Mohammed Vaseem
hi sir,
in .The column type always be “string” type or what else and how will decide the length of this.
thanks sir.
how to retrieve all elements from database if we use table per hierarchy.
i need the query to retrieve all data’s to display
thanks for the tutorial, you rocks 🙂
Just one question: does this example runs fine? I’m getting “mappingException: unknown entity: str.CreditCard” although I’ve revised carefully and I think mapping is right. It happens on saving object. Any advice?
Thanks a lot,
I am also getting the same error, please suggest me have u solved the error…
It works fine for me..
Thanks for sharing
Hi,
Please look into the UML Diagram once ,I think it is in reverse order
Hi Java4s,
it is a best tutorial for Hibernate, all the concepta explanation is very simple and your way of presentation is superb.
I have a doubt that where we can use these type of scenario’s in real time project development
Thanks
Anil
How to retrieve data from DB using this concept table per class.
well explained 🙂
here we are referring to different colums for CreditCardType and ChequeType properties.
If we want, can we have assigned to same column in database for both properties.
hi i think is Payment.java require dcolumn which was added in Payment.hbm.xml as descriminator field.
Can you please explain what is the use of ‘discriminator-value=”CC”‘ in subclass tag below is the example from yours. And where we can configure ‘CC’ or ‘CQ’ to identify this ?.
Thanks,
Gopal
hi Shivateja,
iam Ramakrishna
can you please tell me what is the difference between one to many and many to one, and when we go for it Relationships..
thanks..
Thanks for giving the valuable notes.
in payment.hbm.xml
at line
why we are use class name = “str.Payment”
Hi Siva, This site is really helping me.. Thanks for this and keep it up..
hey pls explain me which realtime scenario which concept of inheritence will be used
Hi Java4s,
Why we need to use below lines in mapping. i didn’t see any explanation given in this section regarding this. can you please provide reason for this ?
Hi,
I understood the concept but I have 1 doubt who will pass the the value for dcolumn ? There is no mapping for this column from java side
nice tutorial …..
but i am getting the issue while running application.
Exception in thread “main” org.hibernate.MappingException: invalid configuration
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1347)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1288)
at com.abhi.SavePayment.main(SavePayment.java:13)
Caused by: org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 26; Document root element “hibernate-Configuration”, must match DOCTYPE root “hibernate-configuration”.
Hi,
Nice tutorial.
Could you please give an example how to print the payment details using HQL.
og4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Exception in thread “main” org.hibernate.InvalidMappingException: Could not parse mapping document from resource payment.hbm.xml
at org.hibernate.cfg.Configuration.addResource(Configuration.java:569)
at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1584)
at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1552)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1531)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1505)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1425)
at ClientForSave.main(ClientForSave.java:11)
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from input stream
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:508)
at org.hibernate.cfg.Configuration.addResource(Configuration.java:566)
… 6 more
Caused by: org.dom4j.DocumentException: Error on line 22 of document : Content is not allowed in trailing section. Nested exception: Content is not allowed in trailing section.
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:499)
… 7 more
i am getting this error i dont know why it cause please sir i want some clarity about this can u please check the code and tell me about this exception
Hi Java4s,
Really u guys rocks….nice one .its very easy to understand and helping me alot
Each time when I run the above example with different value sets it is updating in the DB instead of inserting new row. May I know why its happening like that???
thanks dude……
Caused by: org.hibernate.MappingException: Following super classes referenced in extends not found: null
why this error is comming
Its Best Site to learn new technologies in simple an easiest way.Thanks to person who is writing such best material for us.
Mar 24, 2019 4:03:57 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.4.1.Final}
Mar 24, 2019 4:03:58 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Mar 24, 2019 4:03:58 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Mar 24, 2019 4:03:58 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [oracle.jdbc.driver.OracleDriver] at URL [jdbc:oracle:thin:@localhost:1521:O12CR102]
Mar 24, 2019 4:03:58 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=kale, password=****}
Mar 24, 2019 4:03:58 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Mar 24, 2019 4:03:58 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Mar 24, 2019 4:03:59 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.internal.util.StringHelper.unqualify(StringHelper.java:279)
at org.hibernate.boot.model.source.internal.hbm.AbstractEntitySourceImpl.extractEntityNamingSource(AbstractEntitySourceImpl.java:119)
at org.hibernate.boot.model.source.internal.hbm.AbstractEntitySourceImpl.<init>(AbstractEntitySourceImpl.java:82)
at org.hibernate.boot.model.source.internal.hbm.RootEntitySourceImpl.<init>(RootEntitySourceImpl.java:25)
at org.hibernate.boot.model.source.internal.hbm.EntityHierarchyBuilder.indexMappingDocument(EntityHierarchyBuilder.java:96)
at org.hibernate.boot.model.source.internal.hbm.HbmMetadataSourceProcessorImpl.<init>(HbmMetadataSourceProcessorImpl.java:63)
at org.hibernate.boot.model.source.internal.hbm.HbmMetadataSourceProcessorImpl.<init>(HbmMetadataSourceProcessorImpl.java:40)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.<init>(MetadataBuildingProcess.java:151)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:149)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at sai.test.ClientForSave.main(ClientForSave.java:18)