13

We have a couple of long running back-end processes that take longer than the default 30 seconds.

Our NHibernate version is 2.0.1.4000 and Spring.NET is 1.2.0.20313. NHibernate is configured through Spring.NET this way:

<object id="SessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate20">
    <property name="DbProvider" ref="DbProvider"/> 
    <property name="MappingAssemblies">
        <list>
            <value>SomeKindOfAnItem</value>
        </list> 
    </property>
    <property name="HibernateProperties">
        <dictionary>
            <entry key="expiration" value="120"/>
            <entry key="adonet.batch_size" value="10"/>
            <entry key="cache.provider_class" value="NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache"/>
            <entry key="cache.use_query_cache" value="true"/>
            <entry key="connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
            <entry key="connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
            <entry key="dialect" value="NHibernate.Dialect.MsSql2005Dialect"/>
            <entry key="current_session_context_class" value="Spring.Data.NHibernate.SpringSessionContext, Spring.Data.NHibernate20"/>
            <entry key="show_sql" value="false"/>
        </dictionary>
    </property>
</object>

To get around this, I am trying to set the NHibernate command_timeout to 60 in the Web.config. This is from Web.config:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="command_timeout">60</property>
  </session-factory>
</hibernate-configuration>

Unfortunately this does not work, the command times out after 30 seconds.

I built a console app that calls the DAO just like the web app does it. I have the exact same NHibernate configuration setting in its configuration file. The IDbCommand times out after 60 seconds and not 30, using the setting successfully from the config file.

I tried debugging the app and check if the commandTimeout was set when the DAO assembly is called from the web site. It was.

This is from Visual Studio watch:

((NHibernate.Driver.DriverBase)(((NHibernate.Connection.DriverConnectionProvider) ((NHibernate.Impl.SessionFactoryImpl)session.SessionFactory) .ConnectionProvider).Driver)).commandTimeout: 60

The session is created like this:

ISession session = SessionFactoryUtils.GetSession(HibernateTemplate.SessionFactory, true);

My question is: if the command timeout field was successfully set to 60 from my Web.config, why does it time out after 30 seconds? Any ideas I could try?

ChrisWue
  • 18,612
  • 4
  • 58
  • 83
adomokos
  • 131
  • 1
  • 1
  • 5
  • It would be helpful if you posted a small sample app that reproduced the problem. Writing that small sample app may make it clear to you why it's not working. – Michael Maddox Feb 25 '10 at 10:14
  • Great idea, but I did that already. I built a console app to replicate the problem, but the console app works and the web app does not. – adomokos Mar 02 '10 at 15:53

1 Answers1

12

You could set the timeout as part of the hibernate.connection.connection_string property. I haven't used Spring.Net so I am not sure how it sets up the NHibernate session factory. If you are able to add "Connect Timeout=120" to the connection string. This should increase the time from the default 30 second timeout to 120 seconds.

The following line would go in the web.config:

<property name="connection.connection_string">Server=localhost;initial catalog=nhibernate;User Id=;Password=; Connect Timeout=120;</property>

EDIT

It turns out that there are actually two timeouts. Thanks to adomokos for pointing that out. One for the actual opening of the connection and another for the queries that are executed.

The one for the connection is displayed above, however to set the timeout for a query with NHibernate you use the ICriteria interface.

ICriteria crit = session.CreateCriteria(typeof(Foo)); 
crit.SetTimeout(120); 
List<Foo> fooList = crit.List();

The timeout value is in seconds.

Hope that helps

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Nathan Fisher
  • 7,961
  • 3
  • 47
  • 68
  • 6
    There are two different timeouts: 1) Connection Timeout 2) Command Timeout You are suggesting changing the 1st one, but I need to set the second. Read this for more details: http://tinyurl.com/ybpwkvl – adomokos Feb 25 '10 at 16:44
  • Have you tried the SetTimeout on the ICriteria Interface? which is probably what you are actually after. – Nathan Fisher Feb 26 '10 at 21:50
  • I am not sure I have access to ICriteria. I am trying to save the object through HibernateTemplate: HibernateTemplate.SaveOrUpdate(entity); HibernateTemplate.Flush(); – adomokos Mar 02 '10 at 15:49
  • If you have the session object then you can create a criteria using Session.CreateCriteria. I will edit my answer to explain further. – Nathan Fisher Mar 04 '10 at 22:25
  • Thanks Nate for helping me out! Your code sample would work if I needed to pull data from the data store, however, I get timeout when I try to save the object: "HibernateTemplate.SaveOrUpdate(entity);" How could you set the the timeout on the HibernateTemplate? – adomokos Mar 10 '10 at 21:10
  • Ok so this has more to Saving data rather that retrieveing data. Most of the information regarding timeouts I have found has to do with retrieveing data. There is the SessionFactoryUtils.ApplyTransactionTimeout() method but that requires a sessionfactory and an IQuery or ICriteria. There must be a lot going on for a save to last more that 30 seconds. – Nathan Fisher Mar 11 '10 at 00:41
  • Have a look at http://www.springframework.net/doc-1.1-M1/sdk/1.1/html/Spring.Data.NHibernate~Spring.Data.NHibernate.HibernateTransactionManager.html It may give you some ideas – Nathan Fisher Mar 11 '10 at 00:48