StackOverflowException is thrown when a bag of entities which have a composite-id is retrieved with fetch=join strategy

Description

I have a problem with collections of types that have a composite-id and which I'd like to fetch using a join.
Maybe the problem is related to https://nhibernate.jira.com/browse/NH-766 as well ....

The following case:
I have a class which contains a collection (bag) of objects that have a composite id.
In my mapping file, I specify the fetch strategy as 'join' and I set lazy to false. This means that my entity is retrieved in one query.

However, when I do this, I get a StackOverflowException.

To make things a little bit more concrete, I've attached a testcase (vs.net 2008 solution).
It is a simple winforms application, clicking the button will create an item in the DB and retrieve it back. When fetch='join' is specified in the mapping, a StackOverflowException is thrown. When fetch='select' is specified, everything works fine.
(You'll also find the DBCreate script to create the test-database. I use SQL Server2005 and .NET 2.0)

Environment

None

Attachments

5

Activity

Show:

Fabio Maulo September 14, 2008 at 11:16 AM

I check your mappings and how you are working.
You are doing something not necessary and some other bad practices from the point of view of ORM.

BTW

<class name="Item" table="tblitems" lazy="false">
<id name="Id" column="ItemId">
<generator class="guid.comb" />
</id>

<version name="Version" access="nosetter.camelcase"/>

<property name="Name" column="itemname" />
<list name="ItemDetails" access="field.camelcase-underscore" fetch="join"
lazy="false" cascade="all" table="tblDetails">
<key column="itemid" />
<list-index column="DetailId"/>
<composite-element class="ItemDetail">
<parent name="Owner"/>
<property name="Code"/>
</composite-element>
</list>
</class>
and this is the ItemDetail
public class ItemDetail
{
private string code;
private Item owner;

public Item Owner
{
get { return owner; }
internal set { owner = value; }
}

public string Code
{
get { return code; }
set { code = value; }
}
}

The ItemDetail is a value type (don't have a real ID and can be accessed only trough the parent).
There are various others things to say but is better if you use the users forum for support question
http://groups.google.com.ar/group/nhusers

In the users forum we can help you to choose better/right way to mapping and work with your entities (believe me).
There are some others way to map your two entities depending on what you need in your real app.

Bye Frederik, see you in the forum.

P.S. if you want use composite-id take care to override Equals and hashcode with the properties of the composite-id and, in general, use a specific class to represent the Id or use natural-id.

Frederik Gheysels September 13, 2008 at 2:11 PM

I've added a new testcase (NH1460_FG.zip). I hope it is now more useable for the NH team. I've downloaded the testproject you've refferred to, and created a testfixture which inherits from the abstract TestCase class.

There are 2 tests in the test-case: one which retrieves the entities using a select fetch strategy, and one which retrieves the entities using a join strategy.

While creating the tests, I've also noted another strange thing:

  • when I specify fetch='join' in the mapping file, the retrieval of an entity fails.

  • when I call SetFetchMode on the criteria, and I specify 'SELECT', the retrievel works.

  • when I specify fetch='select' in the mapping file, but override this FetchMode to 'join' by calling SetFetchMode(FetchMode.Join), it seems that retrieving the entity works. ?

(This workaround doesn't solve the problem though when you want to use the ISession.Get() method to retrieve an entity).

Fabio Maulo September 9, 2008 at 9:12 AM

Frederik, if you want create useful tests for NH team please follow want Marco done.
Mean:
1) create a separate folder for test using NHibernate.Tests project or EntitiesPersistenceTestEnvironment.7z available here http://groups.google.com/group/nhusers/files
2) attach the test to the JIRA ticket

An useful help is available here
http://www.nhforge.org/blogs/nhibernate/archive/2008/09/06/prepare-your-system-for-nhibernate.aspx

Hope soon we have another blog-post or a wiki about: How to create a test for a bug

Frederik Gheysels September 9, 2008 at 1:57 AM

Normally, I use transactions, in this example it is possible that I left them out for simplicity
Normally, if I use versions, I use version in all my entities I'll see if I can create a new (better) testcase in the following days.

Fabio Maulo September 8, 2008 at 9:00 PM

@Marco
Your test probably find the same problem but is different than the mapping of Frederik

  • you are not using cascade

  • you are using fetch=join

  • Frederik use versions only for child (another strange thing) and you never use it

All this things are not trivial because each change the why on how NH load object.

Interesting Issue, two test for the same problem.

Details

Assignee

Reporter

Components

Affects versions

Priority

Who's Looking?

Open Who's Looking?
Created August 19, 2008 at 6:28 AM
Updated September 14, 2008 at 11:16 AM
Who's Looking?