• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

problems with hibernate: one-to-many and arrays

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I have never done anything with hibernate before. So I am a bit at a loss now...

I want to map a tree structure to my database. The class I use for the tree is WorkItem. It contains an array of childrens (WorkItem). The problem is that, whatever I try, hibernate cannot write a tree to the database.

My WorkItem class (only the hibernate related attributes and operations are shown):



The hibernate mapping contains a lot of settings that I do not understand. It was automatically generated by XDoclets:



The code using the class looks like this:


The execution of this codes results in the following exception:



The same exception occurs, if I do not save and flush the root before adding the child. Even if I do not use a reference to the same class but another one (e.g. WorkItemChild) I get a similar exception with the difference that the SQL update statement contains the WORK_ITEM_CHILD table instead of the WORK_ITEM table.

I have read the hibernate manual and searched the internet up and down but could not find a solution that helps (there have been others with similar problems). Can you help me out?

Thank you very much!
[ February 22, 2005: Message edited by: George Kippling ]
 
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can't help directly with your array issue. The few associations I have in my model are bidirectional one-to-many inverse relationships using Sets.

However, I can give you another option that will also solve a performace problem you'll find if the size of your tree gets large enough (50-100 items). The problem is that to load a tree you have to load the root item (Q1), then all of its children (Q2), then for each child you must load its children (Q3,4,5,...,n), and so on down the tree until each leaf is found. This results in a query for each item.

One way to solve this problem is to load and build the tree in code. First, add a new column to the table: root_id. It should hold the ID of the root item for the tree. To load a tree, load all items with the desired root_id. To build it, simply insert the items into the tree one-at-a-time.

Reducing n queries for an n-item tree to 1 query will save you a considerable amount of time. Since you'll be managing the relationships in code, it would side-step the current issue you're having with Hibernate.
 
George Kippling
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for the tip. That sounds very useful.
However, this project shall serve as an evaluation of hibernate. The performance issue is only secondary (the tree would be loaded at startup only and the server is destined be always online). So, I first want to try to get it running without handling the relations myself. If it really does not work, I will try out your idea.
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No worries, I'll help with your situation if I can. I believe the problem is that you are saving the parent and not the new child, but the array mapping tells Hibernate not to save the children when you save the parent:In this case you probably want "all" or "all-delete-orphan", but there are other options.
 
George Kippling
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for your answers David!
You are right, cascade must be set to "all" (or anything else related to creating entries). The above mapping is one of the many settings I tested. The setting cascade="all" results in the same problem.

However, in the meantime I have found out two ways to solve the problem:

1. (the ugly way)
Do not save the parent after adding all children, but save the parent and then add and save all children separately.

2. (the way it should be)
a) Add unsaved-value="x" to the ID property of the persistent class
b) do not forget to initialise the ID property with x
c) Add cascade="all" to the array setting
The value x must be a value that is cannot be generated by the database. For example, -1 works for "increment".
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Are you saying that the way it should be worked? Then all is well!

I'm using Integer as my ID field for every entity, and Hibernate handles that automatically without specifying an unsaved value. Sorry, I didn't think of checking that.

Glad it's working for ya!
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok, im with the same problem, but im using in the mapping of the "Class" class

<set name="methods">
<key column="method_id"/>
<one-to-many class="logic.method"/>
</set>

And in the class "Class" there is an atribute of type ArrayList

ArrayList methods;

and it has all the methods of this class.

When saving an error of casting appears. So i change the type of ArrayList to Set (an abstract class, but the same in the mapping tag, so i beliebe this will solve the problem)

but now the system throws the same error in the post, in the same part, when trying to update.

But the set tag doesn't have a cascade atribute.

What do you think?
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think naming a class of yours "Class" is a very, very bad idea. Don't forget about java.lang.Class!
 
Dagoberto Borda
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
jajajajaja

dont worry, it is what i have to model... i speak spanish and the real name of the class is "clase" but i wrote class for you to understand.
 
reply
    Bookmark Topic Watch Topic
  • New Topic