Hello there!
I am trying to implement the "table per class hierarchy. I have a class and 3 subclasses of the classes.
The parent class
Code:
public class Unit implements Serializable {
private Long id;
private Set relatedUnits = new HashSet();
private Set keywords = new HashSet();
private List faqs = new ArrayList();
...
}
Then I have 4 subclasses of Unit as follows
Code:
public class Product extends Unit {
private String name;
private String description;
private String longDescription;
private String attributes;
private String additionalInfo;
private BigDecimal cost;
private BigDecimal salePrice;
private BigDecimal subPrice;
private Set categories = new HashSet();
private Set products = new HashSet(); //related products
...
}
Code:
public class Category extends Unit {
private String name;
private String description;
private String longDescription;
private String additionalInfo;
private String image;
private String thumbnail;
//Relationship
private Set products = new HashSet();
private Set suites = new HashSet();
private Catalog catalog;
...
...
}
Code:
public class Suite extends Unit {
private String name;
private String description;
private String longDescription;
private String additionalInfo;
private String image;
private String thumbnail;
private BigDecimal num0;
private BigDecimal num1;
private BigDecimal num2;
//Relationships
private Set products = new HashSet();
private Set categories = new HashSet();
...
...
}
Code:
public class Coupon extends Unit {
private String code;
private String description;
private String discountType;
//Relationship
private Set products = new HashSet();
....
}
The complete listing of the Unit.hbm.xml file is as below
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.lbkgroup.businessobjects.Unit" table="UNIT">
<id name="id" column="ID" type="long" unsaved-value="null">
<generator class="hilo"/>
</id>
<discriminator column="RELATIONSHIP_TYPE" type="string"/>
<set name="keywords" inverse="false" lazy="true"
table="UNIT_KEYWORD_LINK">
<key column="UNIT_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Keywords" column="KEYWORD_ID"/>
</set>
<list name="faqs"
inverse="true">
<key column="UNIT_ID"/>
<index column="SEQUENCE_NUMBER"/>
<one-to-many class="com.lbkgroup.businessobjects.Faq"/>
</list>
<set name="relatedUnits" inverse="false" lazy="true"
table="UNIT_BINDING" >
<key column="SOURCE_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Unit" column="DESTINATION_ID"/>
</set>
<!-- inverse was true -->
<set name="customers" lazy="true"
inverse="false"
cascade="save-update">
<key column="UNIT_ID"/>
<one-to-many class="com.lbkgroup.businessobjects.Customer"/>
</set>
<!-- inverse was true -->
<set name="salesOrders" lazy="true"
inverse="false"
cascade="save-update">
<key column="UNIT_ID"/>
<one-to-many class="com.lbkgroup.businessobjects.SalesOrder"/>
</set>
<subclass name="com.lbkgroup.businessobjects.Category" discriminator-value="CATEGORY">
<property name="name">
<column name="NAME" />
</property>
<property name="description">
<column name="DESCRIPTION" />
</property>
<property name="longDescription">
<column name="LONG_DESCRIPTION" />
</property>
<property name="additionalInfo">
<column name="ADDITIONAL_INFO" />
</property>
<property name="image">
<column name="IMAGE" />
</property>
<property name="thumbnail">
<column name="THUMBNAIL" />
</property>
<property name="customField1">
<column name="CUSTOM_FIELD1" />
</property>
<property name="customField2">
<column name="CUSTOM_FIELD2" />
</property>
<property name="customField3">
<column name="CUSTOM_FIELD3" />
</property>
<property name="customField4">
<column name="CUSTOM_FIELD4" />
</property>
<!--Category has products -->
<set name="products" inverse="true" lazy="true"
table="UNIT_BINDING" >
<key column="SOURCE_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Product" column="DESTINATION_ID"/>
</set>
<!--Category has suites -->
<set name="suites" inverse="true" lazy="true"
table="UNIT_BINDING" >
<key column="SOURCE_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Suite" column="DESTINATION_ID"/>
</set>
<many-to-one name="catalog"
column="CATALOG_ID"
class="com.lbkgroup.businessobjects.Catalog" />
</subclass>
<subclass name="com.lbkgroup.businessobjects.Suite" discriminator-value="SUITE">
<property name="name">
<column name="NAME" />
</property>
<property name="description">
<column name="DESCRIPTION" />
</property>
<property name="longDescription">
<column name="LONG_DESCRIPTION" />
</property>
<property name="additionalInfo">
<column name="ADDITIONAL_INFO" />
</property>
<property name="image">
<column name="IMAGE" />
</property>
<property name="thumbnail">
<column name="THUMBNAIL" />
</property>
<property name="num0">
<column name="NUM0" />
</property>
<property name="num1">
<column name="NUM1" />
</property>
<property name="num2">
<column name="NUM2" />
</property>
<property name="num3">
<column name="NUM3" />
</property>
<property name="strA">
<column name="STR_A" />
</property>
<property name="strB">
<column name="STR_B" />
</property>
<property name="strC">
<column name="STR_C" />
</property>
<property name="strD">
<column name="STR_D" />
</property>
<property name="sku">
<column name="SKU" />
</property>
<property name="onhandQuantity">
<column name="ONHAND_QUANTITY" />
</property>
<property name="inventoryThreshold">
<column name="INVENTORY_THRESHOLD" />
</property>
<property name="customField4">
<column name="CUSTOM_FIELD4" />
</property>
<!--Suite has products -->
<set name="products" inverse="false" lazy="true"
table="UNIT_BINDING" >
<key column="SOURCE_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Product" column="DESTINATION_ID"/>
</set>
<!--Suite belongs to categories -->
<set name="categories" inverse="false" lazy="true"
table="UNIT_BINDING" >
<key column="DESTINATION_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Category" column="SOURCE_ID"/>
</set>
</subclass>
<subclass name="com.lbkgroup.businessobjects.Coupon" discriminator-value="COUPON">
<property name="code">
<column name="NAME" />
</property>
<property name="description">
<column name="DESCRIPTION" />
</property>
<property name="discountType">
<column name="STR_A" />
</property>
<property name="discountAmount">
<column name="NUM0" />
</property>
<property name="comparator">
<column name="NUM1" />
</property>
<property name="couponType">
<column name="STR_B" />
</property>
<!--Coupon has products -->
<set name="products" inverse="false" lazy="true"
table="UNIT_BINDING" >
<key column="SOURCE_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Product" column="DESTINATION_ID"/>
</set>
</subclass>
<subclass name="com.lbkgroup.businessobjects.Product" discriminator-value="PRODUCT">
<property name="name">
<column name="NAME" />
</property>
<property name="description">
<column name="DESCRIPTION" />
</property>
<property name="longDescription">
<column name="LONG_DESCRIPTION" />
</property>
<property name="attributes">
<column name="STR_D" />
</property>
<property name="additionalInfo">
<column name="ADDITIONAL_INFO" />
</property>
<property name="cost">
<column name="NUM0" />
</property>
<property name="salePrice">
<column name="NUM1" />
</property>
<property name="subPrice">
<column name="NUM2" />
</property>
<property name="quantity">
<column name="ONHAND_QUANTITY" />
</property>
<property name="sku">
<column name="SKU" />
</property>
<property name="image1">
<column name="IMAGE" />
</property>
<property name="image2">
<column name="STR_A" />
</property>
<property name="image3">
<column name="STR_B" />
</property>
<property name="thumbnail">
<column name="THUMBNAIL" />
</property>
<property name="inventoryThreshold">
<column name="INVENTORY_THRESHOLD" />
</property>
<property name="customField1">
<column name="CUSTOM_FIELD1" />
</property>
<property name="customField2">
<column name="CUSTOM_FIELD2" />
</property>
<property name="customField3">
<column name="CUSTOM_FIELD3" />
</property>
<property name="customField4">
<column name="CUSTOM_FIELD4" />
</property>
<!--Product has related products -->
<set name="products" inverse="false" lazy="true"
table="UNIT_BINDING" >
<key column="DESTINATION_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Product" column="SOURCE_ID"/>
</set>
<!--Product has categories -->
<set name="categories" inverse="false" lazy="true"
table="UNIT_BINDING" >
<key column="DESTINATION_ID"/>
<many-to-many class="com.lbkgroup.businessobjects.Category" column="SOURCE_ID"/>
</set>
<many-to-one name="vendor"
column="VENDOR_ID"
class="com.lbkgroup.businessobjects.Vendor"/>
<many-to-one name="warehouse"
column="WAREHOUSE_ID"
class="com.lbkgroup.businessobjects.Warehouse"/>
</subclass>
</class>
</hibernate-mapping>
If lazy = "false" hibernate gives the below error
Code:
net.sf.hibernate.WrongClassException: Object with id: 490010 was not of the specified subclass: com.lbkgroup.businessobjects.Category (loaded object was of wrong class)
hibernate should get the records based on the discriminator values, doesn't it suppose to do that?.
But, If I have lazy = "true" hibernate would get the records from the database (distinguished) by the discriminator value (which is what I want), So, I got by this problem by adding the lazy="true" , but If I go to product details and category details then it would give me
Code:
et.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:209)
at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
at net.sf.hibernate.collection.Set.iterator(Set.java:130)
at org.apache.jsp.pages.layouts.categoryLayout_jsp._jspService(categoryLayout_jsp.java:99)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:704)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:590)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:510)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:966)
at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:581)
at org.apache.struts.tiles.TilesUtilImpl.doInclude(TilesUtilImpl.java:137)
at org.apache.struts.tiles.TilesUtil.doInclude(TilesUtil.java:177)
at org.apache.struts.taglib.tiles.InsertTag.doInclude(InsertTag.java:756)
at org.apache.struts.taglib.tiles.InsertTag$InsertHandler.doEndTag(InsertTag.java:881)
at org.apache.struts.taglib.tiles.InsertTag.doEndTag(InsertTag.java:473)
at org.apache.jsp.pages.categoryView_jsp._jspx_meth_tiles_insert_0(categoryView_jsp.java:141)
at org.apache.jsp.pages.categoryView_jsp._jspService(categoryView_jsp.java:91)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:704)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:474)
Please help me, I spend 3 days on this.
Thanks in advance