Search code examples
nhibernatebulkinsertstateless-session

Unable to bulk insert using NHibernate


I've tried adding bulk inserting to my application, but the Batcher is still NonBatchingBatcher with a BatchSize of 1.

This is using C#3, NH3RC1 and MySql 5.1

I've added this to my SessionFactory

<property name="adonet.batch_size">100</property>

And my code goes pretty much like this

var session = SessionManager.GetStatelessSession(type);
var tx = session.BeginTransaction();
session.Insert(instance);

I'm using HILO identity generation for the instances in question, but not for all instances on the database. The SessionFactory.OpenStatelessSession doesn't take a type, so it can't really know it can do batching on this type, or...?

After some digging into NHibernate, I found something in SettingsFactory.CreateBatcherFactory that might give some additional info

// It defaults to the NonBatchingBatcher
System.Type tBatcher = typeof (NonBatchingBatcherFactory);

// Environment.BatchStrategy == "adonet.factory_class", but I haven't
// defined this in my config file
string batcherClass = PropertiesHelper.GetString(Environment.BatchStrategy, properties, null);
if (string.IsNullOrEmpty(batcherClass))
{
    if (batchSize > 0)
    {
        // MySqlDriver doesn't implement IEmbeddedBatcherFactoryProvider,
        // so it still uses NonBatchingFactory
        IEmbeddedBatcherFactoryProvider ebfp = connectionProvider.Driver as IEmbeddedBatcherFactoryProvider;

Could my configuration be wrong?

  <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory name="my application name">
      <property name="adonet.batch_size">100</property>
      <property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
      <property name="connection.connection_string">my connection string
      </property>
      <property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
      <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
      <!-- To avoid "The column 'Reserved Word' does not belong to the table : ReservedWords" -->
      <property name="hbm2ddl.keywords">none</property>
    </session-factory>
  </hibernate-configuration>

Solution

  • IIRC, batching is currently supported for Oracle and SqlServer only.

    As almost any other aspect of NH, this is extensible, so you can write your own IBatcher/IBatcherFactory and inject them via configuration.

    Sidenote: current version of NH is 3.0 GA.