-->
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.  [ 11 posts ] 
Author Message
 Post subject: Mapping legacy hierarchical data (tree or self-ref. list)
PostPosted: Fri May 20, 2005 3:02 pm 
Newbie

Joined: Thu May 19, 2005 5:02 pm
Posts: 5
Hello!,

I'm trying to construct a mapping to legacy hierarchical data. The data uses a parent_id link to navigate from any node to the root in the tree
(navigating the tree from top-bottom is not required only from bottom to top).
Below is my current mapping, using hbm2ddl I'm able to generate an identical table structure as in our legacy, so I'm almost convinced this mapping is correct.

The problem is at runtime, when creating the session Factory (probably when it reads the hibernate.cfg.xml) that I get a
"Repeated column in mapping for collection" error, I've read some postings suggesting to upgrade to hb3.

Is that the only choice? or is there something that can be changed in this mapping or even the legacy table structure to make it work.
(our preference is not to change the legacy table schema)

Here is some sample data:

PKID NODENAME PARENT_ID
1 A 0 // this is the root
2 A1 1 // second level in tree, parent is #1, first child in this level
3 A11 2 // third level in tree, parent is #2
4 A2 1 // second level in tree, parent is #1, second child in this level

Appreciate any help you can provide in this issue.



Hibernate version: 2.1.8

Mapping documents:

<hibernate-mapping package="persistencetier.tree">
<class name="Tree" table="TREE">
<id name="id" type="integer" column="PKID">
<generator class="increment"/>
</id>
<property name="nodeName" column="NODENAME" not-null="false"
type="string" length="200"/>

<list name="parentList" table="TREE" lazy ="true" >
<key column="PKID" />
<index column="PKID" type="integer" />
<element type="integer" column="PARENT_ID" not-null="true"/>
</list>
</class>
</hibernate-mapping>

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

session = sessionFactory.openSession();
Query query = session
.createQuery("from Tree tree where tree.id = 3");
List result = query.list();

session.close();


Full stack trace of any exception that occurs:

14:49:41,527 INFO SettingsFactory:114 - Use scrollable result sets: true
14:49:41,537 INFO SettingsFactory:117 - Use JDBC3 getGeneratedKeys(): false
14:49:41,537 INFO SettingsFactory:120 - Optimize cache for minimal puts: false
14:49:41,547 INFO SettingsFactory:126 - echoing all SQL to stdout
14:49:41,547 INFO SettingsFactory:129 - Query language substitutions: {}
14:49:41,557 INFO SettingsFactory:140 - cache provider: net.sf.hibernate.cache.EhCacheProvider
14:49:41,627 DEBUG SettingsFactory:173 - Wrap result sets enabled? : false
14:49:41,637 INFO Configuration:1130 - instantiating and configuring caches
14:49:41,767 WARN Configurator:125 - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/C:/jakarta-tomcat-4.1.31/webapps/myapp/WEB-INF/lib/ehcache-0.9.jar!/ehcache-failsafe.xml
14:49:42,158 INFO SessionFactoryImpl:119 - building session factory
14:49:42,168 DEBUG SessionFactoryImpl:125 - instantiating session factory with properties:
net.sf.hibernate.MappingException: Repeated column in mapping for collection: myapp.Tree.parentList column: PKID
at net.sf.hibernate.collection.AbstractCollectionPersister.checkColumnDuplication(AbstractCollectionPersister.java:654)
at net.sf.hibernate.collection.AbstractCollectionPersister.<init>(AbstractCollectionPersister.java:210)
at net.sf.hibernate.collection.BasicCollectionPersister.<init>(BasicCollectionPersister.java:35)
at net.sf.hibernate.persister.PersisterFactory.createCollectionPersister(PersisterFactory.java:55)
at net.sf.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:148)
at net.sf.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:805)
at myapp.Test.myTest(Test.java:120)


Name and version of the database you are using: Oracle 9

The generated SQL (show_sql=true):

no sql generated, fails when reading hibernate.cfg.xml

Debug level Hibernate log excerpt:

all set to DEBUG


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 20, 2005 4:28 pm 
Newbie

Joined: Fri May 20, 2005 4:16 pm
Posts: 13
Code:
<set name="parentList" table="TREE" lazy="true">
  <key column="PKID"/>
  <element type="integer" column="PARENT_ID" not-null="true"/>
</set>


You're using <index> but your table does not have an index column (see http://www.hibernate.org/hib_docs/v3/reference/en/html/collections.html#collections-indexed).


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 20, 2005 4:29 pm 
Newbie

Joined: Fri May 20, 2005 4:16 pm
Posts: 13
Whoops, the top half of my post got lost...

You should rather use a <set> instead of a <list>.

Aside from that, why not directly map real associations instead of integers?


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 20, 2005 4:51 pm 
Newbie

Joined: Thu May 19, 2005 5:02 pm
Posts: 5
Hi Mickey,

Thanks for your response.
The reason to use list instead of set is because I need to be able to
store duplicate elements.

PKID NODENAME PARENT_ID
1 A 0 // this is the root
2 A1 1 // 2nd level in tree, parent is #1, first child
3 A11 2 // 3rd level in tree, parent is #2
4 A2 1 // 2nd level in tree, parent is #1, 2nd child
5 A12 2

In this case the tree is something like this:

A
/ \
A1 A2
/ \
A11 A12


Please notice I'm currently using Hibernate 2.1.8 and the schema (table structure) is a legacy without too many options to be changed.

What do you mean by "map real associations instead of integers?"
It may be that I have to use that because is a legacy table struct.

Thanks for your help !

Yeyo


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 20, 2005 5:04 pm 
Newbie

Joined: Fri May 20, 2005 4:16 pm
Posts: 13
yeyo wrote:
The reason to use list instead of set is because I need to be able to store duplicate elements.


Are you saying a parent can have a child more than one time? As in:

Code:
                    A1
                  /   \
                A2   A2


Like that?


yeyo wrote:
What do you mean by "map real associations instead of integers?" It may be that I have to use that because is a legacy table struct.


Yes, but that doesn't prevent you from having real Parent objects in the parentList collection instead of their FK's.


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 21, 2005 3:03 pm 
Newbie

Joined: Thu May 19, 2005 5:02 pm
Posts: 5
Hi Mickey,

There are no repeated child nodes but repeated instances of parents when navigating from bottom to up.
For instance for the following tree if we start from A11 I should be able to retrieve A11,A1,A or if I'm in node A12 I should get A12,A1,A
I've tried a Set but then it creates the constraint where PARENT_ID must be unique (which can't in this tree)
This sample contains only nodes with 2 childs but the actual data contains nodes with multiple childs.

Thanks !

Code:
PKID  NODENAME        PARENT_ID
===  ========       =======
  1           A                 0         // this is the root
  2           A1               1         // 2nd level in tree, parent is #1, first child
  3           A11             2         // 3rd level in tree, parent is #2
  4           A2               1         // 2nd level in tree, parent is #1, 2nd child
5v          A12              2

In this case the tree is something like this:

                        A
                      /    \
                   A1     A2
                 /     \
             A11     A12


Top
 Profile  
 
 Post subject: Efficient?
PostPosted: Fri Jun 10, 2005 3:04 pm 
Newbie

Joined: Thu May 19, 2005 5:02 pm
Posts: 5
Just to add more info to the previous posting.

Would it be possible to load this type of structure in an efficient manner, without really knowing the number of parents (assuming your are navigating the tree from the leaves to the branch) ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 10, 2005 5:21 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
look at subselect and batchfetcing

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: end of tree?
PostPosted: Thu Jun 16, 2005 4:44 pm 
Newbie

Joined: Thu May 19, 2005 5:02 pm
Posts: 5
Thanks for your info.

Now, how does hibernate know when it's the last node in the recursive list ? By finding a null reference? further more in my case due to the legacy design/data would it be possible to specify different values in this column to indicate the end of the list?

Many thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 5:43 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
i dont get why hibernate should care about when you reach the "end"...the end is when there isn't more references to follow.

regarding have special marker values then look at usertypes.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 11:03 pm 
Beginner
Beginner

Joined: Mon Jun 13, 2005 5:52 pm
Posts: 43
Maybe I'm not reading this right, but if you are always going to be navigating from child to parent, just have the child reference the parent:

Code:
<many-to-one name="parent" class="Node" column="parent_id" outer-join="false"/>


Is that what you need?


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