[nhibernate-development] More multi-threading issues - when loading a child collection

729 views
Skip to first unread message

James Crowley

unread,
May 15, 2010, 6:05:26 AM5/15/10
to nhibernate-...@googlegroups.com
Hi guys,

Just to give you the heads up - there are more multi-threading issues lurking in the latest builds of nHibernate. The IndexOfRangeException one has definitely been squished, but I'm seeing intermittent illegal access to loading collections and and open data readers already being associated with an open connection.... they're all happening when trying to load in a child collection from an entity.

These are *all* happening within NH code. In case anyone can track this down before I have a chance to put more test cases together (last one took me a day of stripping stuff down), here are the stack traces.

Exception #1

NHibernate.LazyInitializationException - illegal access to loading collection
at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:line 460 
at NHibernate.Collection.AbstractPersistentCollection.ReadIndexExistence(Object index) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:line 311 
at NHibernate.Collection.Generic.PersistentGenericMap`2.System.Collections.Generic.IDictionary.ContainsKey(TKey key) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\Generic\PersistentGenericMap.cs:line 106 
at N2.ContentItem.GetDetail[T](String detailName, T defaultValue) in C:\Users\James\Documents\Visual Studio Projects\n2cms\src\N2\ContentItem.cs:line 394 
at TechEye.Web.CmsModel.Pages.Quote.get_Author() in C:\Users\James\Documents\Visual Studio Projects\TheTechEye\TechEye.Web\CmsModel\Parts\Quote.cs:line 29 

Exception #2

NHibernate.Exceptions.GenericADOException - could not initialize a collection batch: [N2.ContentItem.Details#System.Object[]][SQL: SELECT details0_.ItemID as ItemID2_, details0_.ID as ID2_, details0_.Name as Name2_, details0_.ID as ID1_1_, details0_.ItemID as ItemID1_1_, details0_.DetailCollectionID as DetailCo4_1_1_, details0_.Name as Name1_1_, details0_.BoolValue as BoolValue1_1_, details0_.IntValue as IntValue1_1_, details0_.LinkValue as LinkValue1_1_, details0_.DoubleValue as DoubleVa9_1_1_, details0_.DateTimeValue as DateTim10_1_1_, details0_.StringValue as StringV11_1_1_, details0_.Value as Value1_1_, details0_.Type as Type1_1_, contentite1_.ID as ID2_0_, contentite1_.Created as Created2_0_, contentite1_.Published as Published2_0_, contentite1_.Updated as Updated2_0_, contentite1_.Expires as Expires2_0_, contentite1_.Name as Name2_0_, contentite1_.ZoneName as ZoneName2_0_, contentite1_.Title as Title2_0_, contentite1_.SortOrder as SortOrder2_0_, contentite1_.Visible as Visible2_0_, contentite1_.SavedBy as SavedBy2_0_, contentite1_.State as State2_0_, contentite1_.AncestralTrail as Ancestr14_2_0_, contentite1_.Trail as Trail2_0_, contentite1_.VersionIndex as Version16_2_0_, contentite1_.VersionOfID as Version17_2_0_, contentite1_.ParentID as ParentID2_0_, contentite1_.Type as Type2_0_ FROM n2Detail details0_ left outer join n2Item contentite1_ on details0_.LinkValue=contentite1_.ID WHERE (details0_.DetailCollectionID IS NULL) and details0_.ItemID in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
at NHibernate.Loader.Loader.LoadCollectionBatch(ISessionImplementor session, Object[] ids, IType type) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1516 
at NHibernate.Loader.Collection.BatchingCollectionInitializer.Initialize(Object id, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Collection\BatchingCollectionInitializer.cs:line 41 
at NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize(Object key, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Persister\Collection\AbstractCollectionPersister.cs:line 579 
at NHibernate.Event.Default.DefaultInitializeCollectionEventListener.OnInitializeCollection(InitializeCollectionEvent event) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Event\Default\DefaultInitializeCollectionEventListener.cs:line 52 
at NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection collection, Boolean writing) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1637 
at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:line 463 
at NHibernate.Collection.AbstractPersistentCollection.ReadIndexExistence(Object index) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:line 311 
at NHibernate.Collection.Generic.PersistentGenericMap`2.System.Collections.Generic.IDictionary.ContainsKey(TKey key) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\Generic\PersistentGenericMap.cs:line 106 
at N2.ContentItem.GetDetail[T](String detailName, T defaultValue) in C:\Users\James\Documents\Visual Studio Projects\n2cms\src\N2\ContentItem.cs:line 394 
at TechEye.Web.CmsModel.Pages.Quote.get_Author() in C:\Users\James\Documents\Visual Studio Projects\TheTechEye\TechEye.Web\CmsModel\Parts\Quote.cs:line 29 

...

System.InvalidOperationException - There is already an open DataReader associated with this Command which must be closed first.
at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) 
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) 
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) 
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader() 
at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs:line 261 
at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1327 
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 401 
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 236 
at NHibernate.Loader.Loader.LoadCollectionBatch(ISessionImplementor session, Object[] ids, IType type) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1508

Exception #3

NHibernate.Exceptions.GenericADOException - could not initialize a collection batch: [N2.ContentItem.Details#System.Object[]][SQL: SELECT details0_.ItemID as ItemID2_, details0_.ID as ID2_, details0_.Name as Name2_, details0_.ID as ID1_1_, details0_.ItemID as ItemID1_1_, details0_.DetailCollectionID as DetailCo4_1_1_, details0_.Name as Name1_1_, details0_.BoolValue as BoolValue1_1_, details0_.IntValue as IntValue1_1_, details0_.LinkValue as LinkValue1_1_, details0_.DoubleValue as DoubleVa9_1_1_, details0_.DateTimeValue as DateTim10_1_1_, details0_.StringValue as StringV11_1_1_, details0_.Value as Value1_1_, details0_.Type as Type1_1_, contentite1_.ID as ID2_0_, contentite1_.Created as Created2_0_, contentite1_.Published as Published2_0_, contentite1_.Updated as Updated2_0_, contentite1_.Expires as Expires2_0_, contentite1_.Name as Name2_0_, contentite1_.ZoneName as ZoneName2_0_, contentite1_.Title as Title2_0_, contentite1_.SortOrder as SortOrder2_0_, contentite1_.Visible as Visible2_0_, contentite1_.SavedBy as SavedBy2_0_, contentite1_.State as State2_0_, contentite1_.AncestralTrail as Ancestr14_2_0_, contentite1_.Trail as Trail2_0_, contentite1_.VersionIndex as Version16_2_0_, contentite1_.VersionOfID as Version17_2_0_, contentite1_.ParentID as ParentID2_0_, contentite1_.Type as Type2_0_ FROM n2Detail details0_ left outer join n2Item contentite1_ on details0_.LinkValue=contentite1_.ID WHERE (details0_.DetailCollectionID IS NULL) and details0_.ItemID in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
at NHibernate.Loader.Loader.LoadCollectionBatch(ISessionImplementor session, Object[] ids, IType type) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1516 
at NHibernate.Loader.Collection.BatchingCollectionInitializer.Initialize(Object id, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Collection\BatchingCollectionInitializer.cs:line 41 
at NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize(Object key, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Persister\Collection\AbstractCollectionPersister.cs:line 579 
at NHibernate.Event.Default.DefaultInitializeCollectionEventListener.OnInitializeCollection(InitializeCollectionEvent event) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Event\Default\DefaultInitializeCollectionEventListener.cs:line 52 
at NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection collection, Boolean writing) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1637 
at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:line 463 
at NHibernate.Collection.AbstractPersistentCollection.ReadIndexExistence(Object index) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\AbstractPersistentCollection.cs:line 311 
at NHibernate.Collection.Generic.PersistentGenericMap`2.System.Collections.Generic.IDictionary.ContainsKey(TKey key) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Collection\Generic\PersistentGenericMap.cs:line 106 
at N2.ContentItem.GetDetail[T](String detailName, T defaultValue) in C:\Users\James\Documents\Visual Studio Projects\n2cms\src\N2\ContentItem.cs:line 394 
at TechEye.Web.CmsModel.Pages.Quote.get_Author() in C:\Users\James\Documents\Visual Studio Projects\TheTechEye\TechEye.Web\CmsModel\Parts\Quote.cs:line 29 

...


System.InvalidOperationException - Invalid attempt to read when no data is present.
at System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i) 
at System.Data.SqlClient.SqlDataReader.IsDBNull(Int32 i) 
at NHibernate.Driver.NHybridDataReader.IsDBNull(Int32 i) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Driver\NHybridDataReader.cs:line 233 
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Type\NullableType.cs:line 238 
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Type\NullableType.cs:line 195 
at NHibernate.Type.ManyToOneType.Hydrate(IDataReader rs, String[] names, ISessionImplementor session, Object owner) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Type\ManyToOneType.cs:line 83 
at NHibernate.Persister.Entity.AbstractEntityPersister.Hydrate(IDataReader rs, Object id, Object obj, ILoadable rootLoadable, String[][] suffixedPropertyColumns, Boolean allProperties, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2507 
at NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs, Int32 i, Object obj, String instanceClass, EntityKey key, String rowIdAlias, LockMode lockMode, ILoadable rootPersister, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 980 
at NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader dr, Int32 i, ILoadable persister, EntityKey key, LockMode lockMode, String rowIdAlias, EntityKey optionalObjectKey, Object optionalObject, IList hydratedObjects, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 938 
at NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, EntityKey[] keys, Object optionalObject, EntityKey optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 867 
at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 322 
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 467 
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 236 
at NHibernate.Loader.Loader.LoadCollectionBatch(ISessionImplementor session, Object[] ids, IType type) in c:\Users\James\Documents\Visual Studio Projects\External Projects\NHibernate\nhibernate\nhibernate\src\NHibernate\Loader\Loader.cs:line 1508

Thank you

James

---
James Crowley
CEO, developerFusion - the global developer community - http://www.developerfusion.com/
CTO, TechEye - all the technology news unfit for print - http://www.techeye.net/

linkedin: http://linkedin.com/in/jamescrowley
twitter: http://twitter.com/jamescrowley

Richard Brown (gmail)

unread,
May 16, 2010, 7:51:56 AM5/16/10
to nhibernate-...@googlegroups.com
Hi James,
 
Thanks for the heads up.
 
I've tried updating the threading test for http://216.121.112.228/browse/NH-2192.  I've tried various combinations of fetching, and batch sizes, but I can't reproduce the errors you're seeing.
 
Hopefully you'll have more luck than me creating a test case.
 
Cheers,
    Richard

Graham Bunce

unread,
Jun 28, 2010, 6:16:20 PM6/28/10
to nhibernate-development
Any more news on this?

It's definitely an issue lurking in NH somewhere as I'm getting the
same issues with 2.1.2GA. I'm ok with a couple of threads but when I
ramp up to 8 or so, each with its own session and enabling MARS on my
connection string (SQL Server 2008) to try to get round the "open
DataReader associated with this Command " issues, NH just starts to
collapse with the same sort of bugs James is seeing... and it happens
quite quickly too, so it doesn't seem to be a soak test type bug.

I'll see if I can repro via test case too, but it may be tricky which
of course makes it even tricker for you guys to fix it! :)

Fabio Maulo

unread,
Jun 28, 2010, 6:38:46 PM6/28/10
to nhibernate-...@googlegroups.com

Graham Bunce

unread,
Jun 29, 2010, 5:34:16 AM6/29/10
to nhibernate-development
Thanks for the reply Fabio.

However I need to sheepishly hold my hand up here. Looked at the code
again this morning with fresh eyes and had a "Doh!" moment. I
*thought* I was using different sessions per thread but I realised the
problem was that one of the objects was being loaded in the main
thread (with its own session) and used again by the child threads
(which had their own seperate session) and doing a lazy load in the
child sessions.

I fixed this and the problem, so far, has gone away.

Very sorry.... but thank's for the link as I'm doing quite a bit of
multi-threaded stuff with NH at the moment, so it could be useful.

Fabio Maulo

unread,
Jun 29, 2010, 8:34:54 AM6/29/10
to nhibernate-...@googlegroups.com
LOL!!
Again confirmed the rule:
before think in a NH's bug check your code or create a failing test outside your system ;)

The quality is not achieved by chance!!
;)
--
Fabio Maulo

Reply all
Reply to author
Forward
0 new messages