Multiple .Fetch() calls within Future query results in collection that does not persist deletes

Description

I have a "Game" entity that has a static method "GetFuture" which returns an IFutureValue<Game> provided by nHibernate, fairly standard stuff. I recently added an optional Func<IQueryOver<Game, Game>, IQueryOver<Game, Game>> parameter to allow for custom fetching strategies to be supplied to reduce roundtrips further. The code looks like this:

var gameFuture = Game.GetFuture(id, query =>
{
query = query.Fetch(x => x.CompletedActivities).Eager;

if (someCondition)
{
query = query.Fetch(x => x.Items).Eager;
}

return query;
});

Later when I .Remove() an item from the "Items" collection, the delete is not issued to the database. However if I remove the second .Fetch() in the Func<> parameter so that .Items is lazily-loaded later, the delete is issued correctly. I'm unsure if this is a bug or I'm just doing things wrong. Here are the mapping snippets for the two items:

<class name="World.Game" table="Game">
<cache usage="read-write" region="Short" />
<id name="Id">
<generator class="identity" />
</id>

<bag name="Items" inverse="true" cascade="all-delete-orphan" lazy="true" order-by="id ASC">
<cache usage="read-write" region="Short" />
<key column="game" />
<one-to-many class="World.Entities.Entity" />
</bag>
</class>

<class name="World.Entities.Entity" table="WorldContents">
<cache usage="read-write" region="Short" />
<id name="Id">
<generator class="identity" />
</id>
<many-to-one name="Game" />
<property name="X" />
<property name="Y" />
</class>

World.Entities.Entity has a number of joined subclasses.

I get the same problem when using the Linq .Query<T>() provider and when using the .QueryOver<T>() provider.

Using MySQL .NET Connector on .NET 4.

Environment

None

Activity

Frédéric Delaporte 
September 17, 2020 at 6:25 PM

Moved here.

Frédéric Delaporte 
June 6, 2018 at 10:03 AM

Moved here. Can you provide a test case there? See contributing.

Charlotte Thorne 
September 28, 2011 at 5:50 PM

Oh I forgot to add, the GetFuture method body looks like this:

public IFutureValue<Game> GetFuture(int id, Func<IQueryOver<Game, Game>, IQueryOver<Game, Game>> modifier = null)
{
IQueryOver<Game, Game> query = session.QueryOver<Game>().Where(x => x.Id == id);

if (modifier != null)
{
query = modifier(query);
}

return query.FutureValue();
}

Not an Issue

Details

Assignee

Reporter

Labels

Components

Affects versions

Priority

Who's Looking?

Open Who's Looking?
Created September 28, 2011 at 5:45 PM
Updated September 17, 2020 at 6:25 PM
Resolved September 17, 2020 at 6:25 PM
Who's Looking?