Reputation: 1171
We are getting this error after upgrading to NHibernate 2.1.
[QueryException: Cannot simultaneously fetch multiple bags.]
NHibernate.Loader.BasicLoader.PostInstantiate() +418
NHibernate.Loader.Entity.EntityLoader..ctor(IOuterJoinLoadable persister, String[] uniqueKey, IType uniqueKeyType, Int32 batchSize, LockMode lockMode, ISessionFactoryImplementor factory, IDictionary`2 enabledFilters) +123
NHibernate.Loader.Entity.BatchingEntityLoader.CreateBatchingEntityLoader(IOuterJoinLoadable persister, Int32 maxBatchSize, LockMode lockMode, ISessionFactoryImplementor factory, IDictionary`2 enabledFilters) +263
NHibernate.Persister.Entity.AbstractEntityPersister.CreateEntityLoader(LockMode lockMode, IDictionary`2 enabledFilters) +26
NHibernate.Persister.Entity.AbstractEntityPersister.CreateLoaders() +57
NHibernate.Persister.Entity.AbstractEntityPersister.PostInstantiate() +1244
NHibernate.Persister.Entity.SingleTableEntityPersister.PostInstantiate() +18
NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners) +3261
NHibernate.Cfg.Configuration.BuildSessionFactory() +87
Without stepping into the NHibernate source, it doesn't look like I can see which mapping is creating the issue.
It's a very old application with a load of mappings files, lots of mappings have one-to-many bags in them, all lazy instantiated.
For example:
<bag name="Ownership" lazy="true" cascade="all" inverse="true" outer-join="auto" where="fkOwnershipStatusID!=6">
<key column="fkStakeHolderID"/>
<one-to-many class="StakeholderLib.Ownership,StakeholderLib" />
</bag>
maps to:
public virtual IList Ownership {
get {
if (ownership == null)
ownership = new ArrayList();
return ownership;
}
set { ownership = value; }
}
Has anyone seen this error before when upgrading to NHibernate 2.1?
Upvotes: 5
Views: 13125
Reputation: 11
Using FluentNHibernate mapping, I was able to fix this issue by adding .AsSet() in my mapping class:
HasMany(h => h.Modules).KeyColumns.Add("\"ITEMID\"","\"DATAAREAID\"").AsSet();
Upvotes: 1
Reputation: 505
I had this problem because I used two left joins to the same table. Fixed it by using a subquery instead of one of the joins.
Upvotes: 0
Reputation: 587
Another alternative is to map the collections as a set. In Nhibernate 4+ the set collection maps to the ISet found in .NET 4+
I found that I had used a lot of bag mappings due to the lack of a set collection in .NET, now that it's available, I can happily change my classes and mappings.
Upvotes: 15
Reputation: 1171
We found the answer eventually...
We had an entity that had more than 1 bag with a many to many relationship that had
outer-join="true"
set.
This caused the error because when you set outer-join fetching you usually do this to limit the db round-trips, enabling nHibernate to retrieve the whole association in 1 select. In this circumstance this will cause a pre-fetch on each bag immediately causing the error.
We changed that to outer-join="auto" (as below) and they stopped being pre-fetched. This stopped nHibernate attempting to fetch multiple bags simultaneously.
<bag name="Groups" lazy="true" cascade="none" table="dbname..tablename">
<key column="foreignkeyname" />
<many-to-many class="classname.typename,assemblyname"
column="foreignkeyname" outer-join="auto" />
</bag>
Upvotes: 4