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: SELECT n+1 with Set
PostPosted: Wed Sep 17, 2008 8:54 am 
Regular
Regular

Joined: Mon Aug 29, 2005 3:07 pm
Posts: 77
I have a strange situation.
I have 2 classes: Chapter & ChapterName. These 2 classes are mapped to the tables 'Chapter' & 'ChapterName'. (Simple 1:n relation).

My classes look like this:

Code:
    public class Chapter : AuditableEntity<Guid>
    {
        public string ChapterCode
        {
            get;
            set;
        }

        private ISet<ChapterName> _names = new HashedSet<ChapterName> ();

        public ISet<ChapterName> Names
        {
            get
            {
                return _names;
            }
            set
            {
                _names = value;
            }
        }
   }

(AuditableEntity is a base class which contains the Id property, and GetHashcode & Equals overrides).

ChapterCode
Code:
    public class ChapterName : AuditableEntity<Guid>
    {
        public LanguageCode Language
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public Chapter Chapter
        {
            get;
            internal set;
        }       
    }


I've mapped these classes as follows:
Code:
<class name="Chapter" table="Chapter" lazy="false">

    <id name="Id" column="ChapterId">
      <generator class="guid.comb" />
    </id>

    <version name="Version" column="Version" />

    <property name="ChapterCode" column="ChapterCode" />

    <set name="Names" access="field.camelcase-underscore" lazy="false" table="ChapterName" cascade="all-delete-orphan"  inverse="true">
      <key column="ChapterId" />
      <one-to-many class="ChapterName" />
    </set>
       
    <property name="Created" column="CreationDate" />
    <property name="Updated" column="ModificationDate" />
    <property name="CreatedBy" column="CreatedBy" />
    <property name="LastUpdatedBy" column="LastUpdatedBy" />
   
  </class>

  <class name="ChapterName" table="ChapterName" lazy="false">

    <id name="Id" column="ChapterNameId">
      <generator class="guid.comb" />
    </id>

    <property name="Language" column="LanguageCode" />
    <property name="Name" column="Name" />

    <many-to-one name="Chapter" column="ChapterId" class="Chapter" />

    <property name="Created" column="CreationDate" />
    <property name="Updated" column="ModificationDate" />
    <property name="CreatedBy" column="CreatedBy" />
    <property name="LastUpdatedBy" column="LastUpdatedBy" />

  </class>

I don't think that there are any strange things in the mapping ?

Now, what happens:

- Suppose I have 2 records in the ChapterTable (so , 2 chapters).
- Each one of these 2 chapters , has 2 names in the related ChapterName table (one for the french, and one for the english language f.i.).
- I want to retrieve all Chapters with their languages, so I use a Criteria like this:
[code]
ICriteria c = session.CreateCriteria (typeof(Chapter));
c.List<Chapter>();[/]
No problem. All chapters are retrieved, and their names as well.
However, I notice a SELECT n+1 problem.
- This can be solved by setting the fetchmode to 'join', either in the mapping file or in the Criteria by setting SetFetchMode ( Join), so I do this.
- Now what happens , is strange: NHibernate creates a Chapter entity for every record that is in the resultset.
Let me be a bit more specific:

suppose the tables have these contents:
Chapter:
id = 1, name = Chapter1
id = 2, name = Chapter2

ChapterName:
id = 1 , name = "name1", language=1, chapterid=1
id = 2, name = "name2", language=2, chapterid = 1
id = 3, name = "name1", language=1, chapterid = 2

Now, I would suppose that NHibernate returns me 2 Chapter instances. One which has a collection of 2 names, and one which has a collection of one name.
What happens however, is that NHibernate returns me 3 chapters ?
(Twice chapter with id = 1, and once chapter 3). So, this means that for every related chaptername, the chapter is created again ?
What happens ? Am i doing something terribly wrong ?

Hibernate version: 2.0.0.4


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 17, 2008 10:36 am 
Expert
Expert

Joined: Thu Dec 14, 2006 5:57 am
Posts: 1185
Location: Zurich, Switzerland
That's by "design". have a look here:

http://www.hibernate.org/117.html#A12

and

http://www.nhforge.org/wikis/howtonh/get-unique-results-from-joined-queries.aspx

_________________
--Wolfgang


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.