nhibernate / nhibernate-core

NHibernate Object Relational Mapper
https://nhibernate.info
GNU Lesser General Public License v2.1
2.13k stars 928 forks source link

NHibernate error while calling BuildSessionFactory - Source array was not long enough. Check srcIndex and length, and the array's lower bounds #1912

Closed ravidhole closed 5 years ago

ravidhole commented 5 years ago

We are getting below intermittent error on server while calling BuildSessionFactory. When we restart the IIS app pool then it’s working fine on server.

NHibernate Version: 3.3.1.4000 .NET Framework Version: 4.6.1.

Any pointers/suggestions?

ERROR VEST.Common.Infra.Wcf.WcfErrorHandler - Web Service Error occurred: Source: mscorlib Exception Message:Source array was not long enough. Check srcIndex and length, and the array's lower bounds. Stack Trace: at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) at System.Collections.Generic.List1.set_Capacity(Int32 value) at System.Collections.Generic.List1.EnsureCapacity(Int32 min) at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection) at NHibernate.Event.EventListeners.InitializeListeners(Configuration cfg, Object[] list) at NHibernate.Event.EventListeners.InitializeListeners(Configuration cfg) at NHibernate.Cfg.Configuration.BuildSessionFactory() at VEST.Shared.Infra.NHibernate.NHibernateHelper.get_SessionFactory() in NHibernateHelper.cs:line 20

fredericDelaporte commented 5 years ago

Hello,

You have reached the NHibernate bug tracker. Please direct usage and support questions to the user groups: http://nhibernate.info/groups.html

(But most likely this error occurs because your application would attempt building two session factories on concurrent threads from the same Configuration instance. Configuration instances are not thread safe and must not be used by concurrent threads.)

masooda commented 5 years ago

I am facing the exactly same issue on session close and it happen randomly here is the error trace. any one of you can help me in this regards. If i restart the app poll for the website , website start working properly.

Event code: 3005 Event message: An unhandled exception has occurred. Event time: 5/20/2019 1:31:41 AM Event time (UTC): 5/20/2019 6:31:41 AM Event ID: 129a1aea89eb41e48f93468144624290 Event sequence: 146 Event occurrence: 63 Event detail code: 0

Application information: Application domain: /LM/W3SVC/11/ROOT-1-132028010908950616 Trust level: Full Application Virtual Path: / Application Path: C:\Published\gateway-i.cashpass.com\ Machine name: CP-DMZ-APP-02D

Process information: Process ID: 41768 Process name: w3wp.exe Account name: NT AUTHORITY\SYSTEM

Exception information: Exception type: ArgumentException Exception message: Source array was not long enough. Check srcIndex and length, and the array's lower bounds. at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) at System.Collections.Generic.List1.set_Capacity(Int32 value) at System.Collections.Generic.List1.EnsureCapacity(Int32 min) at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection) at NHibernate.Event.EventListeners.InitializeListeners(Configuration cfg, Object[] list) at NHibernate.Event.EventListeners.InitializeListeners(Configuration cfg) at NHibernate.Cfg.Configuration.BuildSessionFactory() at CashPass.I2CGateway.ModelMapper.ModelBuilder.GetSessionFactory(Connections connection) at CashPass.I2CGateway.Domain.SessionManagement.SessionManager.CloseSession() at ASP.global_asax.Application_EndRequest(Object sender, EventArgs e) in c:\Published\gateway-i.cashpass.com\Global.asax:line 46 at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Request information: Request URL: https://aaa.bbb.com/service.asmx Request path: /service.asmx User host address: 34.193.155.41 User:
Is authenticated: False Authentication Type:
Thread account name: NT AUTHORITY\SYSTEM

Thread information: Thread ID: 64 Thread account name: NT AUTHORITY\SYSTEM Is impersonating: False Stack trace: at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) at System.Collections.Generic.List1.set_Capacity(Int32 value) at System.Collections.Generic.List1.EnsureCapacity(Int32 min) at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection) at NHibernate.Event.EventListeners.InitializeListeners(Configuration cfg, Object[] list) at NHibernate.Event.EventListeners.InitializeListeners(Configuration cfg) at NHibernate.Cfg.Configuration.BuildSessionFactory() at CashPass.I2CGateway.ModelMapper.ModelBuilder.GetSessionFactory(Connections connection) at CashPass.I2CGateway.Domain.SessionManagement.SessionManager.CloseSession() at ASP.global_asax.Application_EndRequest(Object sender, EventArgs e) in c:\Published\gateway-i.cashpass.com\Global.asax:line 46 at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Custom event details:

bahusoid commented 5 years ago

Seems like some concurrency related issue present in NHibernate code...

But this part of your stacktrace also looks suspicious:

at NHibernate.Cfg.Configuration.BuildSessionFactory()
at CashPass.I2CGateway.ModelMapper.ModelBuilder.GetSessionFactory(Connections connection)
at CashPass.I2CGateway.Domain.SessionManagement.SessionManager.CloseSession()

BuildSessionFactory should be called only once per app domain creation. Are you calling it on each session open/close?

masooda commented 5 years ago

I am using this inside a web service and only called at the time of application_start and application_end. application is working fine but this issue comes up out of blue without any reason but after restarting the app pool everythign seems normal. I have also check in my code like this

if (_cpGatewaySessionFactory == null) { _cpGatewaySessionFactory = _gatewayConfig.BuildSessionFactory(); }

so BuildSessionFactory for sure called one time only. If this is code issue then when only restarting the app pool fix the issue

bahusoid commented 5 years ago

Also as pointed here it's user responsibility to avoid concurrent calls for BuildSessionFactory. So it's really some concurrency issue but in your code...

so BuildSessionFactory for sure called one time only

No it's not.. You have to add some locking to be sure

masooda commented 5 years ago

can you help me this regard how to add locking

masooda commented 5 years ago

private static object lockObject = new object();

lock (lockObject) { if (sessionFactory == null) { sessionFactory = Configuration().BuildSessionFactory(); } return sessionFactory; }

This is fine approach ?

bahusoid commented 5 years ago

Simplest solution just use Lazy. Something like:

private static Lazy<ISessionFactory> _factory = new Lazy<ISessionFactory>(()=>_gatewayConfig.BuildSessionFactory())

if (_cpGatewaySessionFactory == null)
{
_cpGatewaySessionFactory = _factory.Value;
}
masooda commented 5 years ago

Thank you so much i will try and will let you know if it fix the issue or not.

Thanks again