0

I am getting a hibernate problem. I am trying with no success. I have a schema where there are Category,Attribute,AttributeOption. e.g. a category can be a 'computer', and its respective attribute can be 'RAM','Hard Disk' and e.g. 'RAM' can have attribute option '512MB','1024MB' When I try the above schema with hibernate everything is OK.

Now I have one other requirement. A 'Category' can have many sub categories. e.g. a 'Computer' can have 'laptop' or 'Notebook' as sub categories. Now these subcategories are of the class Category themselves

then I get this scheme:

        1. Category  ------>Category
           A category can contain many sub categories
           e.g. A computer can be a notebook or laptop

        2. Category ------>Attribure
           A category can have many attribute
           A  notebook can have RAM , Hard Disk, Screen Size

        3. Attribute  ------>AttributeOption
           An Attribute can have many attribute options
           e.g. RAM can be 512 MB, 1024 MB

These are my classes without their getters and setters

Class Category:
public class Category implements IsSerializable 
{
    private long CategoryId;
    private String CategoryName;
    private Set <Category> SubCategory=new HashSet <Category> ();
    private Set <Attribute> AllAttributes= new HashSet  <Attribute>();

}
Category Mapping File:


 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 16, 2010 8:07:32 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
    <class name="com.BiddingSystem.Models.Category" table="CATEGORY">
        <id name="CategoryId" type="long">
            <column name="CATEGORYID" />
            <generator class="native" />
        </id>
        <property name="CategoryName" type="java.lang.String">
            <column name="CATEGORYNAME" />
        </property>
        <many-to-one name="ParentCategory" class="com.BiddingSystem.Models.Category">
            <column name="PARENTCATEGORYID" />
        </many-to-one>
        <set name="SubCategory" inverse="true" lazy="true" cascade="all" fetch="join">
            <key>
                <column name="PARENTCATEGORYID" />
            </key>
            <one-to-many class="com.BiddingSystem.Models.Category" />
        </set>
        <set name="AllAttributes" table="ATTRIBUTE" inverse="false" lazy="true">
            <key>
                <column name="CATEGORYID" />
            </key>
            <one-to-many class="com.BiddingSystem.Models.Attribute" />
        </set>
    </class>
</hibernate-mapping>


Class Attribute:
public class Attribute 
{
    private long AttributeId;
    private String AttributeName;
    private Set <AttributeOption> Options= new HashSet <AttributeOption>();
}

Attribute Mapping File:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 16, 2010 5:25:09 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
    <class name="com.BiddingSystem.Models.Attribute" table="ATTRIBUTE">
        <id name="AttributeId" type="long">
            <column name="ATTRIBUTEID" />
            <generator class="native" />
        </id>
        <property name="AttributeName" type="java.lang.String">
            <column name="ATTRIBUTENAME" />
        </property>
        <set name="Options" table="ATTRIBUTEOPTION" inverse="false"  cascade="all">
            <key>
                <column name="ATTRIBUTEID" />
            </key>
            <one-to-many class="com.BiddingSystem.Models.AttributeOption" />
        </set>
    </class>
</hibernate-mapping>


Class AttributeOption:
public class AttributeOption 
{
    private long AttributeOptionId;
    private String Option;
    private String SQLValue;
}
Attribute Mapping File:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 16, 2010 5:25:09 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
    <class name="com.BiddingSystem.Models.AttributeOption" table="ATTRIBUTEOPTION">
        <id name="AttributeOptionId" type="long">
            <column name="ATTRIBUTEOPTIONID" />
            <generator class="native" />
        </id>
        <property name="Option" type="java.lang.String">
            <column name="OPTION" />
        </property>
        <property name="SQLValue" type="java.lang.String">
            <column name="SQLVALUE" />
        </property>
    </class>
</hibernate-mapping>

I am trying the following. I am not getting any error but It is not saving the 'Laptop' which is a category of 'computer' else everything is being saved. So i think the problem is with this part from the category mapping file:

<set name="SubCategory" table="CATEGORY" cascade="all">
            <key>
                <column name="CATEGORYID" />
            </key>
            <one-to-many class="com.BiddingSystem.Models.Category" />
        </set>



This is part of my program  


    Category C=new Category();
    C.setCategoryName("Computer");
    AttributeOption R512= new AttributeOption();R512.setOption("512");R512.setSQLValue("512");
    AttributeOption R1024= new AttributeOption();R1024.setOption("1024");R1024.setSQLValue("1024");


        Category C0= new Category();
    C0.setCategoryName("Laptop");

    C.getSubCategory().add(C0);

    Attribute RAM= new Attribute();
    RAM.setAttributeName("RAM");

    RAM.getOptions().add(R512);RAM.getOptions().add(R1024);

    C.getAllAttributes().add(RAM);



    Transaction tx = null;
    try
    {
        tx=session.beginTransaction();
        tx.begin();
        session.saveOrUpdate(C);
        tx.commit();
        return true;
    }
    catch (Exception e)
    {
        tx.rollback();
        e.printStackTrace();
        return false;
    }

3 Answers 3

1

Something seems wrong with this:

C0.getSubCategory().add(C0);

Shouldn't it be:

C.getSubCategory().add(C0);
Sign up to request clarification or add additional context in comments.

5 Comments

One extra comment: note that in OO programming, the link between two objects is a one-way link, while in relational models it's two way link (you can navigate through the relationship from both sides). So, in this case, it seems that the parents contains a set of subcategories, but the category doesn't know anything about it's parent. Usually, it's a good idea to set both sides of the relationship. See this example from Hibernate test suite: github.com/hibernate/hibernate-core/blob/master/hibernate-core/…
Actually, this is an even better example, as it uses a reference to an object of the same class: github.com/hibernate/hibernate-core/blob/master/hibernate-core/…
I have a new mapping file. My problem now is that there are no link between parent category and child category
What do you mean? No link in code, or in the database? If in the database, you mean that "parent_id" is null?
By looking at your code, it seems you forgot the other side of the link: C0.setParentCategory(C);
0

Hummm, I see some place for improvement in this code : First, you should use the persist() method to persist your entities. Second, to persist a whole object graph, you must either a) persist the sub-objects manually, then the "main" object ; or b) use the Cascade parameter on your relationships so that persisting the "main" object also triggers the persistence of the related sub-objects.

You can find more info on cascading here : http://docs.jboss.org/hibernate/stable/core/reference/en/html/example-parentchild.html#example-parentchild-cascades

1 Comment

Ya, I have placed cascade every where to prevent manual saving to the database
0

Ok, I made it to work

The key to it is the category mapping file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 16, 2010 8:37:02 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
    <class name="com.BiddingSystem.Models.Category" table="CATEGORY">
        <id name="CategoryId" type="long">
            <column name="CATEGORYID" />
            <generator class="native" />
        </id>
        <property name="CategoryName" type="java.lang.String">
            <column name="CATEGORYNAME" />
        </property>

        <many-to-one name="ParentCategory" class="com.BiddingSystem.Models.Category">
            <column name="PARENT_CATEGORY_ID" />
        </many-to-one>

        <set name="SubCategory" lazy="false" cascade="all-delete-orphan" inverse="true">
            <key>
                <column name="PARENT_CATEGORY_ID" />
            </key>
            <one-to-many class="com.BiddingSystem.Models.Category" />
        </set>

        <set name="AllAttributes" table="ATTRIBUTE" inverse="false" lazy="true">
            <key>
                <column name="CATEGORYID" />
            </key>
            <one-to-many class="com.BiddingSystem.Models.Attribute" />
        </set>
    </class>
</hibernate-mapping>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.