One can hibernate one or more than one object to a single table in a database.
Is it possible for an object to be mapped to two different tables? The answer is , No. But the desired effect can be achieved with a minimal effort by taking advantage of Hibernate's support for inheritance hierarchy as follows.
One may wonder where is the need for this kind of behavior.
When an object is persisted in a table that is a queue table or used like a scratch pad (a reader process may delete a record from this table after consuming it), there may be a need to capture the persisted object in a secondary table for logging, auditing or reconciliation purposes.
Here are the steps ...
1. Create a new POJO(say com.mycom.hb.module.SecondaryObject) and make it extend your base Hibernate POJO(say PrimaryObject) that is already hibernated. This object should look simple because the secondary table is exactly same as the primary table.
(It is not a big issue if the secondary table includes more fields. Just implement
the setters and getters for the additional fields if necessary.)
2. Externalize all the property mappings from primary.hbm.xml in a standalone file namely props.xml. This goes a long way and saves a lot of work for secondary table mapping.
3. Use entity reference declaration as shown in hibernate documentation to include property mappings for primary.hbm.xml from props.xml, defined in Step 2. (Chapter 9.1.6 - Table per concrete class, using implicit polymorphism - This is NOT the mapping approach we will take, but used as the reference for entity declaration and references.)
4. Map newly created POJO in secondary.hbm.xml and use entity references to pull in properties from props.xml. The mapping strategy for this approach is going to be "Table per subclass" and the mapping file for the secondary.hbm.xml may look like the following. Remember that making secondary object extend primary object in Java class definition is not just enough. It need to be specified in the joined-subclass definition as follows to get this working.
<?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"
[<!ENTITY myprops SYSTEM "com/mycom/hb/module/props.xml">]>
<hibernate-mapping>
<joined-subclass
name="com.mycom.hb.module.SecondaryObject"
table="SECONDARY_TABLE"
schema="app_schema"
extends="com.mycom.hb.module.PrimaryObject">
<key column="REC_NO" /><!-- primary key -->
&myprops;
</joined-subclass>
</hibernate-mapping>
5. Include secondary.hbm.xml in your hibernate_configuration.cfg.xml
6. Build and populate SecondaryObject and persist them from your data access classes. After persisting SecondaryObject, you could find data actually persisted in both PRIMARY_TABLE and also a copy of it in SECONDARY_TABLE.
No comments:
Post a Comment