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