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.  [ 4 posts ] 
Author Message
 Post subject: 3 level relationship depersists incorrectly... kinda
PostPosted: Thu Feb 21, 2008 2:15 pm 
Newbie

Joined: Wed Oct 31, 2007 1:50 pm
Posts: 13
I have the following sample which highlights a real problem I'm having.

Person -< Order -< OrderItem (mappings below)

When saving the I get 1 person record, 1 order record and 3 OrderItems with all relationships working (I Save person and everything cascade's correctly). I have the bidirectional relationship working with inverse on the appropriate collections/bags.

My problem is that when I Get( typeof(Person), id ), I'm getting the Person as expected, but with 3 Orders and each OrderItem replicated in each Order.

I've confirmed that this is caused by the fetch="join" in the Order.Items bag. If changed to Select it works just fine, but I'd like to avoid the extra roundtrip. Here are some snippets of the mappings:

Code:
<class name="Example.Model.Person, Example" table="Person">
  <id name="Id" column="Id" type="Int64">
    <generator class="identity"/>
  </id>
 
  <property name="Name" column="Name" type="String" not-null="true" />

  <bag name="Orders" table="Order" fetch="join" cascade="all" inverse="true">
    <key column="PersonId" />
    <one-to-many class="Example.Model.Order, Example" />
  </bag>
</class>


Code:
<class name="Example.Model.Order, Example" table="[Order]">
  <id name="Id" column="Id" type="Int64">
    <generator class="identity"/>
  </id>

  <many-to-one class="Example.Model.Person, Example" name="Person" column="PersonId" not-null="true" cascade="all" />
 
  <property name="PlacedOn" column="PlacedOn" type="DateTime" not-null="true" />

  <bag name="Items" table="OrderItem" fetch="join" cascade="all" inverse="true">
    <key column="OrderId" />
    <one-to-many class="Example.Model.OrderItem, Example" />
  </bag>
</class>


Code:
<class name="Example.Model.OrderItem, Example" table="OrderItem">
  <id name="Id" type="Int64">
    <generator class="identity" />
  </id>
 
  <many-to-one class="Example.Model.Order, Example" name="Order" column="OrderId" not-null="true" cascade="all" />
  <many-to-one class="Example.Model.Product, Example" name="Product" column="ProductId" cascade="all" />

  <property name="Size" column="Size" type="String" not-null="false" />
  <property name="Color" column="Color" type="String" not-null="false" />
</class>


I can provide a full sample VS project if it helps.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 21, 2008 2:36 pm 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
Interesting. I wonder what would happen if you used a set rather than a bag in this scenario? Would it filter out the duplicates?

Sorry, no answers - just speculation.

Symon.

_________________
Symon Rottem
http://blog.symbiotic-development.com


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 21, 2008 2:54 pm 
Newbie

Joined: Wed Oct 31, 2007 1:50 pm
Posts: 13
Quote:
Interesting. I wonder what would happen if you used a set rather than a bag in this scenario? Would it filter out the duplicates?


I'll be damned. I wouldn't have realized. I guess I need to familiarize myself a little better with the collection/set types. Thanks a lot.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 21, 2008 3:52 pm 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
No problems.

I know that when you call List() on a query to return the results of a joined entity (eg, SELECT k from Cat c JOIN c.Kittens k WHERE k.Color = "brown") sometimes the result set has more than one instance of the same object.

This is because the underlying result set from the database has one of each of the first level objects (Cat, in this case) but the joined result set may contain duplicates (ie. two Cats can have the same Kitten in their Kittens collection - which works from a biological perspective as long as one of the cat's is male and the other is female...ok, you probably already knew that).

In fact, the duplicates are only duplicate references in the list - there's only one actual instance of each entity. For some reason the developers of the original Hibernate made the decision that it wasn't appropriate to dedupe the result set.

Under these circumstances one of the methods for getting rid of the duplicates is to pass them into a Set since sets don't allow duplicates.


Cheers,

Symon.

_________________
Symon Rottem
http://blog.symbiotic-development.com


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