include 'set arithabort on' statement when preforming CUD.

599 views
Skip to first unread message

Jason Meckley

unread,
Aug 7, 2009, 3:13:17 PM8/7/09
to nhusers
I have a MS Sql Server db with indexed, computed columns. I'm trying
to insert a record utilizing session.SaveOrUpdateCopy(entity); but the
following error is thrown:

NHibernate.HibernateException: An exception occurred when executing
batch queries ---> System.Data.SqlClient.SqlException: UPDATE failed
because the following SET options have incorrect settings:
'ARITHABORT'.

Is there a way to configure NH to output the sql
SET ARITHABORT ON
<actual nh sql>
SET ARITHABORT OFF

ideally I only want to configure this for the 2 specific tables that
have computed columns, but if I need to apply it to all tables (or if
this a simple 1 line config for all tables) I can use that as well.

thank you in advance

Jason Meckley

unread,
Aug 7, 2009, 5:34:24 PM8/7/09
to nhusers
it seems either an interceptor or listener would be the best choice
for this. however I cannot seem to locate the proper method/listener
to implement so far I have tried:
EmptyInterceptor
SetSession (to get access to session)
AfterTransactionBegins
BeforeTransactionCompletes

BeforeTransactionCompletes will fire to set arithabort off.
AfterTransactionBegins will either throw a Session Is Closed exception
if I don't check the session is open or it will not fire my sql
statement if I check for Session.IsOpen because the session is closed.
I am trying to execute
Session.CreateSQLQuery("set arithabort on").ExecuteUpdate();
at this point.

I have tried
Session.CreateSQLQuery("set arithabort on").ExecuteUpdate();
with the following listeners
IFlush
IAutoFlush
IPreInsert
IPreUpdate
IPreDelete

IFlush will execute the arithabort statement, but it doesn't execute
the actual flushing (CUD statements)
IAutoFlush doesn't fire the listener at all
(I may have the behavor of these listeners switched)

the Pre Insert/Update/Delete listeners throw an exception that the id
property of the entity I am trying to modify is null. Maybe this is
because I'm injecting the SqlQuery just before the actual update?

Fabio Maulo

unread,
Aug 8, 2009, 8:54:08 AM8/8/09
to nhu...@googlegroups.com
IInterceptor.OnPrepareStatement
or
YourCustomDrive.GenerateCommand

2009/8/7 Jason Meckley <jasonm...@gmail.com>



--
Fabio Maulo

Jason Meckley

unread,
Aug 8, 2009, 10:07:49 AM8/8/09
to nhusers
thank you fabio. it took some trail and error, but i came up with this
public class ArithabortInterceptor : EmptyInterceptor
{
private readonly Configuration Configuration;

public ArithabortInterceptor(Configuration configuration)
{
Configuration = configuration;
}

public override SqlString OnPrepareStatement(SqlString sql)
{
if (!IsAModifyOperation(sql)) return sql;
if (!IsModifingTheOrderHeader(sql)) return sql;
return InjectArithabortStatement(sql);
}

private SqlString InjectArithabortStatement(SqlString sql)
{
return new SqlString("SET ARITHABORT ON ").Append(sql);
}

private bool IsAModifyOperation(SqlString sql)
{
var operations = new[] {"INSERT", "UPDATE", "DELETE"};
return operations.Any(operation => sql.ToString().Contains
(operation));
}

private bool IsModifingTheOrderHeader(SqlString sql)
{
var mapping = Configuration.GetClassMapping(typeof(Order).FullName);
var table = mapping.Table.Name;
return sql.ToString().Contains(table);
}
}

On Aug 8, 8:54 am, Fabio Maulo <fabioma...@gmail.com> wrote:
> IInterceptor.OnPrepareStatementor
> YourCustomDrive.GenerateCommand
>
> 2009/8/7 Jason Meckley <jasonmeck...@gmail.com>
Reply all
Reply to author
Forward
0 new messages