-->
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.  [ 13 posts ] 
Author Message
 Post subject: Tree Structure - Not working, why?
PostPosted: Thu Feb 09, 2006 11:04 pm 
Newbie

Joined: Thu Feb 09, 2006 10:50 pm
Posts: 7
I'm trying to make a tree structure using HB, But a got a weird problem I don't know how to solve:

I insert some nodes to the tree, everything go ok.

When I try to get them back(createCriteria and/or createQuery), the getChildren List is ALWAYS null. getParent works fine.

Can you guys help me? Thank you a lot.


All files:


Hibernate version:305

Mapping:
Code:
<hibernate-mapping>
    <class name="br.com.meta.satie.hb.sistema.Node" lazy="true">
        <id name="id">
            <generator class="increment"/>
        </id>

        <property name="title"/>
        <property name="path"/>
        <property name="iconPath"/>
        <property name="sequence"/>
       
       <list name="children" table="node"
            cascade="all-delete-orphan" inverse="true" lazy="true">
          <key column="idParent" />
          <index column="sequence" />
          <one-to-many class="br.com.meta.satie.hb.sistema.Node" />
      </list>

        <many-to-one
        name="parent"
        class="br.com.meta.satie.hb.sistema.Node"
        column="idParent"
        cascade="all"/>

    </class>
</hibernate-mapping>


INSERT
Code:
        Transaction tx = session.beginTransaction();
       
        Node ROOT = new Node();
        ROOT.setTitle("ROOT");
        ROOT.setParent(null);
        ROOT.setSequence(0);
        ROOT.setPath("ROOT path");
       
        Node CHILD1 = new Node();
        CHILD1.setTitle("CHILD1");
        CHILD1.setParent(ROOT);
        CHILD1.setSequence(0);
        CHILD1.setPath("CHILD1 path");
       
        Node CHILD2 = new Node();
        CHILD2.setTitle("CHILD2");
        CHILD2.setParent(ROOT);
        CHILD2.setSequence(0);
        CHILD2.setPath("CHILD2 path");
               
       
        session.save(ROOT);
        session.save(CHILD1);
        session.save(CHILD2);
       
        tx.commit();


QUERY:
Code:
        Query select = session.createQuery("from Node n left join fetch n.children");
        List<Node> nodes = select.list();
        for(Node n: nodes) {
            System.out.println("NODE: " + n.getId() + " PARENT: " + n.getParent() + " CHILDREN: " + n.getChildren());
         
        } 



Name and version of the database you are using:
MySQL

The generated SQL (show_sql=true):

Code:
Hibernate: /* insert br.com.meta.satie.hb.sistema.Node */ insert into Node (title, path, iconPath, sequence, idParent, id) values (?, ?, ?, ?, ?, ?)
Hibernate: /* insert br.com.meta.satie.hb.sistema.Node */ insert into Node (title, path, iconPath, sequence, idParent, id) values (?, ?, ?, ?, ?, ?)
Hibernate: /* insert br.com.meta.satie.hb.sistema.Node */ insert into Node (title, path, iconPath, sequence, idParent, id) values (?, ?, ?, ?, ?, ?)
Hibernate: /* from Node p left join fetch p.children c */ select node0_.id as id0_, children1_.id as id1_, node0_.title as title0_0_, node0_.path as path0_0_, node0_.iconPath as iconPath0_0_, node0_.sequence as sequence0_0_, node0_.idParent as idParent0_0_, children1_.title as title0_1_, children1_.path as path0_1_, children1_.iconPath as iconPath0_1_, children1_.sequence as sequence0_1_, children1_.idParent as idParent0_1_, children1_.idParent as idParent0__, children1_.id as id0__, children1_.sequence as sequence0__ from Node node0_ left outer join Node children1_ on node0_.id=children1_.idParent

SYSTEM OUTPUT:
NODE: 1 PARENT: br.com.meta.satie.hb.sistema.Node@8e32e7 CHILDREN: null
NODE: 2 PARENT: null CHILDREN: null
NODE: 2 PARENT: null CHILDREN: null
NODE: 3 PARENT: br.com.meta.satie.hb.sistema.Node@8e32e7 CHILDREN: null
BUILD SUCCESSFUL (total time: 5 seconds)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:20 pm 
Beginner
Beginner

Joined: Wed Jan 25, 2006 10:16 am
Posts: 44
Location: Bangalore
Did you have any sequence values for the object you are trying to retrieve by List?

If you don't have it might return null?

:-)

_________________
Please vote if my Postings helps. :-)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:24 pm 
Newbie

Joined: Thu Feb 09, 2006 10:50 pm
Posts: 7
I tried to set some diferent values on sequence field: (1, 2) for child nodes and (0, 1) for root node... got the same result. :(


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:34 pm 
Beginner
Beginner

Joined: Wed Jan 25, 2006 10:16 am
Posts: 44
Location: Bangalore
I dunno if this will work. But try to add this to your list and <many-to-one> mapping ------ fetch="join".

Reply if it helped and even if hadn't :-)

_________________
Please vote if my Postings helps. :-)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:37 pm 
Newbie

Joined: Thu Feb 09, 2006 10:50 pm
Posts: 7
Same problem...

Look, I found an example but it does not works too (getChilds)

http://www.satollo.com/en/programming/h ... -tree.html


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:45 pm 
Beginner
Beginner

Joined: Wed Jan 25, 2006 10:16 am
Posts: 44
Location: Bangalore
Just do a quick check if,
hibernate.max_fetch_depth is set to 0 in your hibernate file.

_________________
Please vote if my Postings helps. :-)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:50 pm 
Newbie

Joined: Thu Feb 09, 2006 10:50 pm
Posts: 7
yep:

<property name="hibernate.max_fetch_depth">0</property>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:52 pm 
Beginner
Beginner

Joined: Wed Jan 25, 2006 10:16 am
Posts: 44
Location: Bangalore
If it is 0, it might not allow joins to fetch data.
That's what the hibernate manual says.

Quote:
Outer join fetching may be disabled globally by setting the property hibernate.max_fetch_depth to 0. A setting
of 1 or higher enables outer join fetching for one-to-one and many-to-one associations which have been
mapped with fetch="join".


Try removing it.

_________________
Please vote if my Postings helps. :-)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 11:57 pm 
Newbie

Joined: Thu Feb 09, 2006 10:50 pm
Posts: 7
It was not set before, I just inserted it now (and removed), both ways give me the same result (getChildren == null)

A lot of people had the same problem (google it) I'm starting to think it's a hibernate problem.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 10, 2006 12:11 am 
Newbie

Joined: Thu Feb 09, 2006 10:50 pm
Posts: 7
Yes, I almost sure this is a hibernate bug (some bidirectional problem)

On the first insert-code, I tried to use session.flush but I got some problem, now I tried to addChildren instead of setting parent and it is working. This is VERY crazy, because the data on the mysql table is the same in both ways.

Code:
      Transaction tx = session.beginTransaction();
       
        Node ROOT = new Node();
        ROOT.setTitle("ROOT");
        ROOT.setParent(null);
        ROOT.setSequence(3);
        ROOT.setPath("ROOT path");
           
        ArrayList l = new ArrayList();
        Node CHILD1 = new Node();
        CHILD1.setTitle("CHILD1");
        CHILD1.setSequence(1);
        CHILD1.setPath("CHILD1 path");
        l.add(CHILD1);
       
       
        Node CHILD2 = new Node();
        CHILD2.setTitle("CHILD2");
        CHILD2.setSequence(2);
        CHILD2.setPath("CHILD2 path");
        l.add(CHILD1);
               
        ROOT.setChildren(l);
       
        session.save(ROOT);
        session.save(CHILD1);
        session.save(CHILD2);
       
        tx.commit();   


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 10, 2006 12:13 am 
Beginner
Beginner

Joined: Wed Jan 25, 2006 10:16 am
Posts: 44
Location: Bangalore
Did you check your databse if the values has been set correctly?

I tried to reproduce your issue and the only problem i face is that when i retrieve a list and order it by the index sequence, it inserts null values in the list.

Like,
Say i have three children with sequence values 3, 4 and 7.
Now on retrieving the list i get 7 values in the list with first and second being null and the third being the child with sequence value 3, 4th being the child with sequence value 4 adn 5 and 6 are again null with 7th child being the child with sequence value 7.

But i do get a children list collection with all the 7 values.

_________________
Please vote if my Postings helps. :-)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 10, 2006 12:20 am 
Beginner
Beginner

Joined: Wed Jan 25, 2006 10:16 am
Posts: 44
Location: Bangalore
Hah!!! Now is see your problem.
You specify that this child node has the parent_id as the parent node's id.

But the parent node's id is generated only after the parent node is actually inserted into the database. so it should first insert the parent node, get the id of it and use it to set the ParentId of the child node.

So it should be cascaded. But if you save your three nodes as,

session.save(Parent node);
session.save(Child node1); // it doesn't know the parent node's ID.
session.save(Child node2); // it doesn't know the parent node's ID.


On your second approach,
You don't have to give,

session.save(Child node1);
session.save(Child node2);

It's enough if you just say session.save(parent node);
Try now it'll work for you.

It's not a hibernate problem. :-)


Please vote if my postings helped you.

_________________
Please vote if my Postings helps. :-)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 10, 2006 12:28 am 
Newbie

Joined: Thu Feb 09, 2006 10:50 pm
Posts: 7
Thank you a lot, now I think I know what is the problem,

I don't know why, but even using session.flush() HB it's not returning child nodes if I'm using just child.setParent(root) to save them. And, if I'm using just root.addChildren(arraylist) without setParent on every child, it doesn't works too.


IMHO:
The HB reference says session.flush avoid this (you don't need to set on both sides of the relationship) but somehow it's doesn't works when the relationship it's on the same table. (Using 2 diferent tables, this works)

This "solved" my problem (I'm making some tests):

Code:
    public void addChild(Node child) {
        if (children == null) children = new ArrayList<Node>();
        child.setParent(this);
        children.add(child);
    }


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 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.