-->
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.  [ 2 posts ] 
Author Message
 Post subject: Hibernate list and idbag
PostPosted: Tue May 08, 2007 9:30 pm 
Newbie

Joined: Tue May 08, 2007 8:43 pm
Posts: 5
Hi,

My question is more of a design issue than a technical problem. Part of it has been covered in the post http://forum.hibernate.org/viewtopic.php?t=973053.


I have two model objects : Page and Line. A page may have multiple lines, and a line must belong to exactly one page. I also want to put some ordering on the lines of a pages, since I obviously don't want them to appear in a random fashion. So far, I have the following tables (simplified for the sake of the example; the underlined columns are the primary keys) :
    Page (page_id)

    Line (line_id, page_id, line_number)

The "number" column identifies the position of a given line on a page. I assume there is no such thing as a "null" line, so the "number" values of the lines of any page is sequential (it won't be possible to have for a given page a line with number=3, another with number=5 but nothing with number=4). Also notice that (page_id, number) would be a perfectly valid composite primary key, but I chose to use a surrogate key instead. I added a constraint in my database that ensures the uniqueness of (page_id, line_number) regardless of what Hibernate may or may not guarantee, since this database will also be accessed by non-Hibernate applications.


I want a bidirectional mapping between Line and Page, so it seems that I have two options to deal with this :
    Either use a <list> mapping

    Or use an <bag> with an "order by" clause (unless I'm mistaken an <idbag> mapping is useful for many-to-many mappings with a surrogate key, which is not the case here)


In either case, my understanding is that I'll need to specify inverse="false" and a not null constraint for the key column on the one-to-many side, and update="false" insert="false" on the many-to-one side (especially in the case of the list, where I feel that I shouldn't have to deal with the index myself - this should be handled automatically by Hibernate and the list itself).


So on the whole, the mapping file should look like this for Line (in the case of the bag, I should probably drop the 'insert="false" update="false"' clauses for the 'number' property since I'm not sure the bag could automatically assign this property when I add an object to the "Lines" collection - in this case, I would have to assign it myself):

Code:
   <class name="Line" table="LINE">
      <id name="id" column="line_id">
         <generator class="native">
            <param name="sequence">line_line_id_seq</param>
         </generator>
      </id>
      
      <property name="number" column="line_number"  insert="false" update="false"/>

      <many-to-one name="page" column="page_id" class="Page" insert="false" update="false" />
   </class>


In the first case for Page:

Code:
   <class name="Page" table="PAGE">
      <id name="id" column="page_id">
         <generator class="native">
            <param name="sequence">page_page_id_seq</param>
         </generator>
      </id>

      <list name="lines" lazy="true" cascade="all">
         <key column="page_id" not-null="true" />
         <list-index base="0" column="line_number" />
         <one-to-many class="Line" />
      </list>
   </class>


Whereas in the second case:

Code:
   <class name="Page" table="PAGE">
      <id name="id" column="page_id">
         <generator class="native">
            <param name="sequence">page_page_id_seq</param>
         </generator>
      </id>

      <bag name="lines" lazy="true" order-by="line_number" cascade="all">
         <key column="page_id" not-null="true" />
         <one-to-many class="Line" />
      </bag>
   </class>



My instinct tells me to use the first solution. Is this the correct way of doing it? Or is there any reason to prefer the second one, or even another way of doing it?


Last edited by Tama on Wed May 09, 2007 10:56 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed May 09, 2007 10:50 pm 
Newbie

Joined: Tue May 08, 2007 8:43 pm
Posts: 5
Precision: I use Hibernate 3.1.3 (which seems to be the latest in maven repositories) and the latest Hibernate Tools


I got my example to work moreorless using the <list> mapping:
    * If I use a unidirectional mapping, I can perform queries such as "from Page" and browse the properties of the result using the Hibernate Tools; a simple Hibernate test app that iterates over the Pages and the Lines of each Page will work.

    * If I use a bidirectional mapping, the same simple Hibernate test app will still work. However I can't browse the result of queries using the Hibernate Tools - I get the accurate number of results in the "Hibernate Query Result" tab, but I cannot browse their properties in the "Properties" tab (whereas I could in the case of the unidirectional mapping !)
    I don't know if this is a bug of the Hibernate Tools or the result of an incorrect mapping that Hibernate can deal with, but not the Hibernate Tools.



Additionnaly, I would have expected that the following set of instructions would insert a new Line at index 0 and shift all the other lines to the right (ie index = index + 1) for the page with id = 4:
Code:
      Page page = (Page) session.get(Page.class, 4);
      Line line = new Line();
      page.getLines().add(0, line);
      session.save(page);


Instead of this, I get an insert error because the insert query performed by Hibernate results in a duplicate (page_id, line_number). Is there a way to get around this?


And I'm still not sure whether a list was the right choice or not...


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