-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Circular Entity - Once and for all?
PostPosted: Mon Feb 09, 2004 11:11 pm 
Newbie

Joined: Mon Feb 09, 2004 10:00 pm
Posts: 15
I haven't found a single, complete example of a circular relationship in an entity. I promise that any information I get during this thread, I'll add to a document in the wiki or somewhere.

What I have works, but it is extremely inefficient. Consider a simple Category object that contains a circular reference to itself. This allows a Category to have children, and those categories can have categories, etc. This is basically a tree structure - it could be a list of folders on a hard drive, or an organizational structure in a LDAP directory. Anything like that.

Code:
class Category {
    private String _id;
    private String _name;
    private Category _parent;
    private Set _children = new HashSet();

    public void addChildCategory(Category childCategory) {
        Category parent = childCategory.getParent();
        if (parent != null)
            parent.removeChildCategory(childCategory);
        childCategory.setParent(this);
        _children.add(childCategory);
    }

    public void removeChildCategory(Category childCategory) {
        childCategory.setParent(null);
        _children.remove(childCategory);
    }

    // Obligitory equals, hashcode, and toString method.
}


The table definition looks something like:

Code:
create table CATEGORY (
   CATEGORY_ID         VARCHAR(40)                    not null,
   PARENT_ID           VARCHAR(40)                    null,
   CATEGORY_NAME       VARCHAR(255)                   not null,
   constraint PK_CATEGORY primary key (CATEGORY_ID)
)


I have been using the following mapping file:

Code:
<class
   name="us.oh.state.dot.jpp.domain.Category"
   table="CATEGORY"
   dynamic-update="false"
   dynamic-insert="false">

   <id
      name="id"
      column="CATEGORY_OID"
      type="java.lang.String"
      unsaved-value="null">
      <generator class="uuid.hex" />
   </id>

   <property
      name="name"
      type="java.lang.String"
      update="true"
      insert="true"
      column="NAME_TXT" />

   <many-to-one
      name="parent"
      class="my.package.Category"
      cascade="save-update"
      outer-join="auto"
      update="true"
      insert="true"
      column="PARENT_OID" />

   <many-to-one
      name="children"
      class="my.package.Category"
      cascade="all"
      outer-join="true"
      update="true"
      insert="true"
      column="PARENT_OID" />


So, what's the problem. Well, at first nothing seemed to be out of the ordinary until I was doing some load testing.

I created the top level category object (parent = null), and then I inserted 500 additional category objects using code similar to the following:

Code:
parentCategory = new Category("Parent");
categoryDAO.createCategory(parentCategory);

Category lastCategory = parentCategory;

for (int i = 0; i < 500; i++) {
   Category cat = new Category("Category " + i);
   categoryDAO.createCategory(cat);

   lastCategory.addChildCategory(cat);
   categoryDAO.updateCategory(lastCategory);
   
   lastCategory = cat;
}


If the mapping is functionally correct, it may be excessive. As anyone who looks at the table definition, the entire relationship is built on the PARENT_ID being set on the original insert of a child category. The step of updating a Set of children to a parent category is just an unnecessary database activity, since the parent category is relatively unaffected by the action.

Where should I focus my effort to reduce the amount of database activity? The DAO design requires all database activity to take place in the DAO, therefore the getChildren() method cannot be lazily loaded.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2004 12:50 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
HUH???

This is bizarre. You map a Set-valued property with <many-to-one>??


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 10, 2004 9:49 am 
Newbie

Joined: Mon Feb 09, 2004 10:00 pm
Posts: 15
Yes, sorry. That mapping file was not the correct one. Here is the one that works correctly, but excessively.

Code:
<class
   name="us.oh.state.dot.jpp.domain.Category"
   table="JPP_CATEGORY"
   dynamic-update="false"
   dynamic-insert="false">

   <id
      name="id"
      column="CATEGORY_OID"
      type="java.lang.String"
      unsaved-value="null">
      <generator class="uuid.hex" />
   </id>

<property
   name="name"
   type="java.lang.String"
   update="true"
   insert="true"
   column="NAME_TXT" />

<many-to-one
   name="parent"
   class="my.package.Category"
   cascade="save-update"
   outer-join="auto"
   update="true"
   insert="true"
   column="PARENT_OID" />

<set
   name="children"
   lazy="false"
   inverse="true"
   cascade="all"
   sort="unsorted" >

   <key column="PARENT_OID" />

   <one-to-many
      class="my.package.Category" />
</set>


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.