Newsletter |
Hibernate Inheritance: Table Per subClass Hierarchy
Hibernate » on Jun 21, 2011 { 27 Comments } By Sivateja
This is also just like previous example, but some changes are there, in table per class hierarchy all the data was saved in a single table but here,
x number of classes = x number of tables in the database
If we save the CreditCard class object, then first hibernate will saves the data related to super class object into the super class related table in the database and then CreditCard object data in CreditCard related table in the database, so first base class data will be saved
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
All are same but mapping file is different than previous example..
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" /> <property name="amount" column="amt" /> <joined-subclass name="str.CreditCard" table="CreditCard"> <key column="dummy1" /> <property name="CreditCardType" column="cctype" length="10" /> </joined-subclass> <joined-subclass name="str.Cheque" table="Cheque"> <key column="dummy2" /> <property name="ChequeType" column="cqtype" length="10" /> </joined-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:
- In the mapping file, <key –> element is because, once we save the derived class object, then hibernate will first save the baseclass object then derived class object right ..!, so at the time of saving the derived class object hibernate will copy the primary key value of the base class into the corresponding derived class, see in the above output 10 copied into dummy1 column of CreditCard table and 11 copied into Dummy2 column of the cheque table
- that’s it friends, nothing to explain…. 😉
You Might Also Like
::. About the Author .:: | ||
Comments
27 Responses to “Hibernate Inheritance: Table Per subClass Hierarchy”
Some really prize blog posts on this website , bookmarked .
Thank you Glenn….!!!!
awesome website yar……… i recommended to every one go throw this …….. indepth explanations
@John Thank you
I got an error
Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
i think, already table is there first drop the existing table
Thanks..its a great help for me 🙂
This Concept of Table for sub class what the explination you have given when it is executed in Eclipse it is giving
Exception in thread “main” org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update…
To Anand,
You are Error because you are using the database of previous example ie payment table contains only 2 columns not 4 as in the previous example so it may be a chance of constraint error to this particular example
Good explanation. Thanks.
I have a question here.
As each class in java has base class as Object class,where this object is getting saved every time?
really awesome… Nice explanation
Lots of thanks
wow!… what a beautiful explanation
i god mad while reading your explanation.. we can easily understand for big concepts…so nice….
if you have any updates, plz send into my mail: rajjmucharla@gmail.com
thanks,
the best tutorial site ever seen….awesome… 😀
Thanks for the clear cut explanation..
You stated “so at the time of saving the derived class object hibernate will copy the primary key value of the base class into the corresponding derived class”
Here Question is.. If we have the composite primary key than should we create two dummy columns in each sub classes or any approach. Please explain.
Thanks.
Good explanation. Thanks.
I have a question here.
As each class in java has base class as Object class,where this object is getting saved every time?
really really very very very good website blog….i insisted every one to refer this blog…….
please give one exmple per load operation on table per class,table per subclass and table concert class
hi siva,
what if parent class is abstract?
hell sir,
I have a question here
when we run the program again give the following exception
Exception in thread “main” org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2250)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2678)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at str.ClientForSave.main(ClientForSave.java:33)
Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (SYSTEM.SYS_C004176) violated
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10657)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
… 14 more
This website gave me too much help. Day by day i’m learning myself, my confidence increasing automatically bcoze of you. i owe you thank you sir
Thanks and regard
Ashish
Hi
very Good. Thanks.
i got issue ……
Cannot add or update a child row: a foreign key constraint fails (`abhi/credit`, CONSTRAINT `FK78CA9719C05CE0B0` FOREIGN KEY (`dummy1`) REFERENCES `pmt` (`pid`))
Please help me,
Running above example, I am getting following error:
Object saved successfully…..!!
Hibernate: insert into PAYMENT (amt, pid) values (?, ?)
Exception in thread “main” org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2228)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2656)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:52)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at shilpi.ClientForSave.main(ClientForSave.java:33)
Caused by: java.sql.BatchUpdateException: Field ‘dcolumn’ doesn’t have a default value
at com.mysql.jdbc.SQLError.createBatchUpdateException(SQLError.java:1158)
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1773)
at com.mysql.jdbc.PreparedStatement.executeBatchInternal(PreparedStatement.java:1257)
at com.mysql.jdbc.StatementImpl.executeBatch(StatementImpl.java:959)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
… 14 more
Caused by: java.sql.SQLException: Field ‘dcolumn’ doesn’t have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1751)
… 18 more
Nice explanation….
Hi,
I am getting the below error, please help as it is urgently required.
Caused by: org.dom4j.DocumentException: Error on line 1 of document http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd : The markup declarations contained or pointed to by the document type declaration must be well-formed. Nested exception: The markup declarations contained or pointed to by the document type declaration must be well-formed.
to achieve this, is it required to have the relation between the tables?
Hi Admin,
I do have one question regarding the inheritance mapping in hibernate, So the question is that do we need to create table explicitly in the database before using it in hibernate means we cannot use CREATE property of hbm2ddl.auto. ?
Why I am asking this because whenever I am trying to execute my program using SINGLE_TABLE inheritance type to test it and it is throwing an error everytime.