-->
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.  [ 5 posts ] 
Author Message
 Post subject: [Parent/Child] Parent included in its children set ?
PostPosted: Sat Jul 14, 2007 11:42 am 
Newbie

Joined: Thu Jul 12, 2007 4:21 pm
Posts: 3
Location: Barboleuse, Switzerland
Hi !

I have a parent/child relationship between categories, all stored in the same table. I generated the DAO using Hibernate Synchronizer. When I create a category and ask for its children, the resulting set contains the category itself instead of being empty, as expected.

Why is that ?

Thanks in advance !

Hibernate version: 3.2.1ga

Mapping documents:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
   <class name="Category" table="category">
      <meta attribute="sync-DAO">true</meta>
      <id name="id" type="integer" column="categoryID">
         <generator class="sequence" />
      </id>

      <property name="name" column="name" type="string"
         not-null="true" length="200" />
      <many-to-one name="parentID" column="parentID" class="Category"
         not-null="false">
      </many-to-one>

      <set name="categories" inverse="true" lazy="true">
         <key column="categoryID" />
         <one-to-many class="Category" />
      </set>

   </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

CategoryBLL.java
Code:
public class CategoryBLL {

   /**
    * Creates a new category with the given name and no parent;
    * @param name The name of the category to create.
    * @return The newly created category.
    */
   public static Category create(String name) {      
      return create(name, null);
   }
   
   /**
    * Creates a new category with the given name and parent.
    * @param name The name of the new category.
    * @param parent The parent of the new category.
    * @return The newly created category
    */
   public static Category create(String name, Category parent) {
      if (null == name || name.equals("")) {
         throw new IllegalArgumentException("name cannot be null or empty");
      }
      
      HibernateUtil.init();
      
      CategoryDAO dao = (CategoryDAO) CategoryDAO.getInstance();
      
      Transaction tx = dao.getSessionFactory().openSession().beginTransaction();
      
      Category c = new Category();
      c.setName(name);
      c.setParentID(parent);
      
      dao.save(c);
      
      if (null != parent) {
         addChild(parent, c);
      }
      
      tx.commit();
      
      return c;
   }
   
   /**
    * Adds a child to a parent category.
    * @param parent The parent category.
    * @param child The child category to add.
    */
   public static void addChild(Category parent, Category child) {
      if (null == parent) {
         throw new IllegalArgumentException("parent cannot be null");
      }
      
      if (null == child) {
         throw new IllegalArgumentException("child cannot be null");
      }
      
      if (null == parent.getCategories()) {
         parent.setCategories(new HashSet<Category>());
      }
      
      parent.getCategories().add(child);
      
      update(parent);
   }
   
   /**
    * Updates a modified category.
    * @param category The category to update.
    */
   public static void update(Category category) {
      HibernateUtil.init();
      
      CategoryDAO dao = (CategoryDAO) CategoryDAO.getInstance();
      
      dao.update(category);
   }
   
   /**
    * Gets a category by its name.
    * @param id The name of the category to get.
    * @return The category with given name.
    */
   public static Category getByName(String name) {
      HibernateUtil.init();
      
      CategoryDAO dao = (CategoryDAO) CategoryDAO.getInstance();

      Query q = dao.getSession().createQuery("from Category where name = :name");
      q.setParameter("name", name);
      
      return (Category) q.uniqueResult();
   }
}


CategoryBLLTest.java
Code:
public class CategoryBLLTest {
   @Before
   public void initDB() {
      _RootDAO.initialize();
   }
   
   @After
   public void closeSession() {
      _RootDAO.closeCurrentSession();
   }

   @Test
   public void testBugGetCategories() {
      String name = "Watches";
      
      CategoryBLL.create(name);
      
      Category c1 = CategoryBLL.getByName(name);
      
      Set<Category> children = c1.getCategories();
      
      Assert.assertEquals(0, children.size());
   }
}


Name and version of the database you are using: HSQLDB 1.8.0.7

The generated SQL (show_sql=true):

Code:
Hibernate: select next value for hibernate_sequence from dual_hibernate_sequence
Hibernate: insert into category (name, parentID, categoryID) values (?, ?, ?)
Hibernate: select category0_.categoryID as categoryID37_, category0_.name as name37_, category0_.parentID as parentID37_ from category category0_ where category0_.name=?
Hibernate: select categories0_.categoryID as categoryID1_, categories0_.categoryID as categoryID37_0_, categories0_.name as name37_0_, categories0_.parentID as parentID37_0_ from category categories0_ where categories0_.categoryID=?

_________________
Wookai


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 14, 2007 1:32 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Your categories set is using the wrong ID - try parentID instead.

Mike


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 14, 2007 2:33 pm 
Newbie

Joined: Thu Jul 12, 2007 4:21 pm
Posts: 3
Location: Barboleuse, Switzerland
Are you sure ?

I have a many to one relationship from parentID (to categoryID), and a one to many relationship from categoryID (to parentID).

And I think this is what my mapping file describes, doesn't it ?

_________________
Wookai


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 14, 2007 2:50 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
With
<set>
<key column="categoryID" />
...
you're saying that the set should be populated with table entries where the categoryID column equals your object's primary key. However, your object's primary key _IS_ the categoryID column which is why you see the parent Category in the child set.

Think about a one-to-many relationship with a different table (this helped me). Each entry has its primary key but also has a second column with the primary key of the parent (the 'one' end of the relationship).

Mike


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jul 15, 2007 3:48 am 
Newbie

Joined: Thu Jul 12, 2007 4:21 pm
Posts: 3
Location: Barboleuse, Switzerland
You're absolutely right !

Thanks a lot for finding my error and explaining it ;) !

_________________
Wookai


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.