Could not synchronize database state with session- Nhibernate and Rebus concurrency issue - nhibernate

When using Rebus with Nhibernate, while storing the subscriber details in table getting error like
NHibernate.Event.Default.AbstractFlushingEventListener
NHibernate.AdoNet.TooManyRowsAffectedException: Unexpected row count: 5; expected: 1
at NHibernate.AdoNet.Expectations.BasicExpectation.VerifyOutcomeNonBatched(Int32 rowCount, IDbCommand statement)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
at NHibernate.Action.EntityUpdateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
This may happen due to all subscriber concurrency, because If I use debugger, then it work unexpectedly as enough time passes.
Getting exception in this code
public void Insert(ISagaData sagaData, string[] sagaDataPropertyPathsToIndex)
{
try
{
var nSagaData = new NDbSagaData
{
Id = sagaData.Id,
Revision = sagaData.Revision++,
Data = JsonConvert.SerializeObject(sagaData, Formatting.Indented, Settings)
};
PersistenceManager.Save(nSagaData);
}
catch (Exception ex)
{
_log.Error("Insert Exception " + ex.Message);
System.IO.File.AppendAllText("C:\\TestFolder\\WriteText.txt", "Insert fromSource - " + ex.Message);
throw new OptimisticLockingException(sagaData, ex);
}
}
and it says, 'Unexpected row count: 3; expected: 1'
What will be the reason?

It looks like you have implemented a saga persister based on NHibernate, and it seems like it has detected a race condition, which I am guessing results in a rolled-back transaction.
I guess the question is why a race condition occurred. The "unexpected row count" exception occurs when NHibernate's optimistic concurrency check fails, but in that case I would have expected a message saying "unexpected row count 0; expected 1".
If I were you, I would use Rebus' built-in SQL Server saga persister, as it seems you are serializing the saga data into a single column anyway.

Related

Ignite.Net 2.12.0 fails on startup

Since upgrading to Apache.Ignite 2.12.0, Ignite fails to start up with the following error:
Unhandled exception. Apache.Ignite.Core.Common.IgniteException: Failed to start Ignite.NET, check inner exception for details
System.ArgumentException: Seek before origin: -1953261975
at Apache.Ignite.Core.Impl.Memory.PlatformMemoryStream.Seek(Int32 offset, SeekOrigin origin)
at Apache.Ignite.Core.Impl.Binary.BinaryReader.ReadHandleObject[T](Int32 pos, Type typeOverride)
at Apache.Ignite.Core.Impl.Binary.BinaryReader.Read[T](Func`1 readFunc, Byte expHdr)
at Apache.Ignite.Core.Impl.Binary.BinaryReader.Read[T](Func`2 readFunc, Byte expHdr)
at Apache.Ignite.Core.Impl.Binary.BinaryReader.ReadString()
at Apache.Ignite.Core.Configuration.DataRegionConfiguration..ctor(IBinaryRawReader reader)
at Apache.Ignite.Core.Configuration.DataStorageConfiguration.<>c__DisplayClass27_0.<.ctor>b__0(Int32 x)
at System.Linq.Enumerable.SelectRangeIterator`1.ToArray()
at Apache.Ignite.Core.Configuration.DataStorageConfiguration..ctor(IBinaryRawReader reader)
at Apache.Ignite.Core.IgniteConfiguration.ReadCore(BinaryReader r)
at Apache.Ignite.Core.IgniteConfiguration.Read(BinaryReader binaryReader)
at Apache.Ignite.Core.IgniteConfiguration..ctor(BinaryReader binaryReader, IgniteConfiguration baseConfig)
at Apache.Ignite.Core.Impl.Ignite.<GetConfiguration>b__87_0(IBinaryStream s)
at Apache.Ignite.Core.Impl.PlatformJniTarget.OutStream[T](Int32 type, Func`2 readAction)
at Apache.Ignite.Core.Impl.PlatformTargetAdapter.DoInOp[T](Int32 type, Func`2 action)
at Apache.Ignite.Core.Impl.Ignite.GetConfiguration()
at Apache.Ignite.Core.Impl.Ignite.SetCompactFooter()
at Apache.Ignite.Core.Impl.Ignite..ctor(IgniteConfiguration cfg, String name, IPlatformTargetInternal proc, Marshaller marsh, IList`1 lifecycleHandlers, UnmanagedCallbacks cbs)
at Apache.Ignite.Core.Ignition.OnStart(GlobalRef interopProc, IBinaryStream stream)
at Apache.Ignite.Core.Impl.Unmanaged.UnmanagedCallbacks.OnStart(Int64 memPtr, Int64 unused, Int64 unused1, Void* proc)
at Apache.Ignite.Core.Impl.Unmanaged.UnmanagedCallbacks.InLongLongLongObjectOutLong(Int32 type, Int64 val1, Int64 val2, Int64 val3, IntPtr arg)
at Apache.Ignite.Core.Impl.Unmanaged.Jni.Callbacks.InLongLongLongObjectOutLong(IntPtr env, IntPtr clazz, Int64 igniteId, Int32 op, Int64 arg1, Int64 arg2, Int64 arg3, IntPtr arg)
Any assistance would be appreciated

VB.net Console Application crashes when trying to save a .pfd with PDF Box

Im trying to change a PDF file with the PDFBox Library in vb.net,
evrything went fine until i was trying to save the PDF, it crashes with the following stacktrace:
org.apache.pdfbox.exceptions.COSVisitorException wurde nicht behandelt.
HResult=-2146233088
Message=java.security.NoSuchAlgorithmException: class configured for MessageDigest(provider: SUN)cannot be found.
Message (Exception)=java.security.NoSuchAlgorithmException: class configured for MessageDigest(provider: SUN)cannot be found.
Source=pdfbox-1.8.7
Source (Exception)=pdfbox-1.8.7
StackTrace:
bei org.apache.pdfbox.pdfwriter.COSWriter.write(PDDocument doc)
bei org.apache.pdfbox.pdmodel.PDDocument.save(OutputStream output)
bei org.apache.pdfbox.pdmodel.PDDocument.save(File file)
bei org.apache.pdfbox.pdmodel.PDDocument.save(String fileName)
bei PDFAnfertigen.Module1.TextAusPDFAuslesen(String pPDFPfad) in C:\Users\fengels\Documents\Visual Studio 2013\Projects\PDFAnfertigen\PDFAnfertigen\Module1.vb:Zeile 44.
bei PDFAnfertigen.Module1.Main() in C:\Users\fengels\Documents\Visual Studio 2013\Projects\PDFAnfertigen\PDFAnfertigen\Module1.vb:Zeile 12.
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()
InnerException: java.security.NoSuchAlgorithmException
HResult=-2146233088
Message=class configured for MessageDigest(provider: SUN)cannot be found.
Message (Exception)=class configured for MessageDigest(provider: SUN)cannot be found.
Source=IKVM.OpenJDK.Core
Source (Exception)=IKVM.OpenJDK.Core
StackTrace:
bei sun.security.jca.GetInstance.getInstance(String type, Class clazz, String algorithm)
bei java.security.Security.getImpl(String , String , String )
bei java.security.MessageDigest.getInstance(String algorithm)
bei org.apache.pdfbox.pdfwriter.COSWriter.write(PDDocument doc)
InnerException: java.lang.ClassNotFoundException
HResult=-2146233088
Message=sun.security.provider.MD5
Message (Exception)=sun.security.provider.MD5
Source=IKVM.Runtime
Source (Exception)=IKVM.Runtime
StackTrace:
bei IKVM.NativeCode.java.lang.Class.forName0(String name, Boolean initialize, ClassLoader loader)
bei java.lang.Class.forName0(String , Boolean , ClassLoader )
bei java.lang.Class.forName(String className, CallerID )
bei java.security.Provider.Service.getImplClass()
InnerException:
I have no idea what this means and googling it ain´t that effective, this is my Code, even i think it has nothing to do with it
Dim objPDFDokument As PDDocument = PDDocument.load(pPDFPfad)
Do
eingefügt = False
While intSeite < objPDFDokument.getDocumentCatalog.getAllPages.size
Dim Dateipfad() As String = NachDateiZuordnungSuchen(intSeite, pPDFPfad)
If Dateipfad IsNot Nothing Then
For Each strDateipfad As String In Dateipfad
If Path.GetExtension(strDateipfad).Equals(".pdf") Then
Dim objPDFeinfuegDatei As PDDocument = LadePdf(strDateipfad)
For i As Integer = 0 To objPDFeinfuegDatei.getDocumentCatalog.getAllPages.size - 1
eingefügt = True
intSeite += 1
objPDFDokument = FuegeSeiteEin(objPDFDokument, objPDFeinfuegDatei, intSeite)
Next
End If
Next
End If
intSeite += 1
End While
Loop Until eingefügt = False
objPDFDokument.save(Path.Combine(Path.GetDirectoryName(pPDFPfad), "test.pdf"))
objPDFDokument.close()

InsertOnSubmit() causes MissingMethodException

I'm trying to implement SQL CE in a WP7 Mango project, but now I'm encountering this error when I try to insert/save an object to my DB.
My code below:
public static void Save(MyObject myobject)
{
using (DBDataContext dc = new DBDataContext(DBDataContext.ConnectionString))
{
dc.MyObject.InsertOnSubmit(myobject);
dc.SubmitChanges();
}
}
When code hits the insertonsubmit line, it breaks with
MissingMethodException was unhandled
MissingMethodException
And that's all it tells me.
Call stack:
mscorlib.dll!System.Activator.InternalCreateInstance(System.Type type, bool nonPublic, ref System.Threading.StackCrawlMark stackMark) + 0xe4 bytes
mscorlib.dll!System.Activator.CreateInstance(System.Type type) + 0x2 bytes
System.Data.Linq.dll!System.Data.Linq.WorkAround.ActivationHelper.CreateInstance(System.Type type)
System.Data.Linq.dll!System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.CreateDataCopy(object instance) + 0x12 bytes
System.Data.Linq.dll!System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.StartTracking() + 0x16 bytes
System.Data.Linq.dll!System.Data.Linq.ChangeTracker.StandardChangeTracker.OnPropertyChanging(object sender, System.ComponentModel.PropertyChangingEventArgs args) + 0x16 bytes
System.Data.Linq.dll!System.Data.Linq.ChangeTracker.StandardChangeTracker.Attach(object obj) + 0x1f bytes
System.Data.Linq.dll!System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(System.Data.Linq.Mapping.MetaType mt, object obj, System.Collections.Generic.Dictionary<object,object> visited, bool recurse, int level) + 0x4e bytes
System.Data.Linq.dll!System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(object obj, bool recurse) + 0x1d bytes
System.Data.Linq.dll!System.Data.Linq.ChangeTracker.StandardChangeTracker.Track(object obj) + 0x3 bytes
System.Data.Linq.dll!System.Data.Linq.Table<FotoDok.EkstraFeltMulighed>.InsertOnSubmit(FotoDok.EkstraFeltMulighed entity) + 0xac bytes
FotoDok.dll!FotoDok.EkstraFeltMulighed.Gem(FotoDok.EkstraFeltMulighed ekstrafeltmulighed) Line 70 + 0xc bytes C#
FotoDok.dll!FotoDok.opdaterProjekter.behandlProjektJson(Newtonsoft.Json.Linq.JObject o) Line 202 + 0x7 bytes C#
FotoDok.dll!FotoDok.opdaterProjekter.ReadCallbackValgteProjekter.AnonymousMethod__1(System.Windows.Controls.CheckBox delChk, Newtonsoft.Json.Linq.JObject delO) Line 141 + 0x7 bytes C#
mscorlib.dll!System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo rtmi, object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object parameters, System.Globalization.CultureInfo culture, bool isBinderDefault, System.Reflection.Assembly caller, bool verifyAccess, ref System.Threading.StackCrawlMark stackMark)
mscorlib.dll!System.Reflection.RuntimeMethodInfo.InternalInvoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture, ref System.Threading.StackCrawlMark stackMark) + 0x168 bytes
mscorlib.dll!System.Reflection.MethodBase.Invoke(object obj, object[] parameters) + 0xa bytes
mscorlib.dll!System.Delegate.DynamicInvokeOne(object[] args) + 0x98 bytes
mscorlib.dll!System.MulticastDelegate.DynamicInvokeImpl(object[] args) + 0x8 bytes
mscorlib.dll!System.Delegate.DynamicInvoke(object[] args) + 0x2 bytes
System.Windows.dll!System.Windows.Threading.DispatcherOperation.Invoke() + 0xc bytes
System.Windows.dll!System.Windows.Threading.Dispatcher.Dispatch(System.Windows.Threading.DispatcherPriority priority) + 0x83 bytes
System.Windows.dll!System.Windows.Threading.Dispatcher.OnInvoke(object context) + 0x8 bytes
System.Windows.dll!System.Windows.Hosting.CallbackCookie.Invoke(object[] args) + 0x19 bytes
System.Windows.dll!System.Windows.Hosting.DelegateWrapper.InternalInvoke(object[] args) + 0x2 bytes
System.Windows.RuntimeHost.dll!System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(System.IntPtr pHandle, int nParamCount, System.Windows.Hosting.NativeMethods.ScriptParam[] pParams, ref System.Windows.Hosting.NativeMethods.ScriptParam pResult) + 0x5e bytes
[External Code]
I've managed to insert other objects, using the same approach just fine, but I can't figure out what makes this object any different.
I solved it myself, googling even more about it (Typical, searching for hours, then right after making a post here I stumble on an answer..)
Aparrently my classes must have an empty contructor, if they don't the error appears.
So adding empty constructors to my classes solved it.
I would like to add that the constructor must be public. I have the same problem, but in my model class I had empty internal constructor.

Inconsistent SQLDateTime Overflow with NHibernate

We have a very strange error that sometimes we get this error when we want to save something from our WCF service. The object that we are saving contains NO invalid datetimes, we all check them before we save. When we see this error the database hangs sometimes and the WCF is in a faulty state. When I restart the DB and the IIS web app where the WCF is hosted and try to save again. It works..
We are clueless so if any one has some advice, please share
Following is the error:
2010-03-05 10:21:34,311 [5] ERROR ProjectX.Business.TTExceptionLogger - Exception somewhere in ReceiveResultsForMobile(): {0}
Castle.Services.Transaction.CommitResourceException: Could not commit transaction, one (or more) of the resources failed ---> System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
at System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value)
at System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value)
at System.Data.SqlClient.MetaType.FromDateTime(DateTime dateTime, Byte cb)
at System.Data.SqlClient.TdsParser.WriteValue(Object value, MetaType type, Byte scale, Int32 actualLength, Int32 encodingByteSize, Int32 offset, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
at NHibernate.Action.EntityUpdateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
at Rhino.Commons.NHibernateTransactionAdapter.Commit()
at Rhino.Commons.Facilities.RhinoTransactionResourceAdapter.Commit()
at Castle.Services.Transaction.AbstractTransaction.Commit()
--- End of inner exception stack trace ---
at Castle.Services.Transaction.AbstractTransaction.Commit()
at Castle.Services.Transaction.StandardTransaction.Commit()
at Castle.Facilities.AutomaticTransactionManagement.TransactionInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at IReceiveServiceProxy61c28a82c9a24e96957e32292b924889.Save(Receive instance)
at WcfInterfaceService.MobileServices.SaveReceiveLines(IEnumerable1 receiveLines, String warehouseCode, String username, String deviceNumber, Boolean removeOldReceiveLines) in D:\Project Docs\Clients\ClientX 09.08\Projects\ProjectX\ProjectX.WcfInterfaceService\MobileServices.svc.cs:line 567
at WcfInterfaceService.MobileServices.ProcessReceiveResults(List1 receiveLines, String warehouseCode, String username, String deviceNumber) in D:\Project Docs\Clients\ClientX 09.08\Projects\ProjectX\ProjectX.WcfInterfaceService\MobileServices.svc.cs:line 770
at WcfInterfaceService.MobileServices.ProcessResultsFromMobile(String receiveResult, String warehouseCode, String username, String deviceNumber) in D:\Project Docs\Clients\ClientX 09.08\Projects\ProjectX\ProjectX.WcfInterfaceService\MobileServices.svc.cs:line 668
Are you running SQL Server 2008? I ran into this same error today when using SQL Server 2008. On the database I had set the column to "date" instead of "datetime" because I do not care about the time portion. But there isn't a "date" data type in .NET so you use datetime.
For me I was passing along null datetime values which defaults to something like 1/1/0001 12:00:00 AM. So I was getting the same error you are seeing because it included the time portion.
For me I had to make my datetime value nullable and I also had to use the MsSql2008Dialect in NHibernate which supports the date datatype. More info about NHibernate and SQL Server 2008 here.
I'd check to make sure your database data type is set correctly and that you are using the MsSql2008Dialect if you are using SQL Server 2008.
I have two questions before I can give you an answer:
What kind of database do you use?
What kind of date is causing the exception?
Guess: you are using a database that has a smaller datetime range or accuracy than you use in your code. In that case, the exception is not caused by NHibernate, but by a feature of the database. It's not a bug but a feature.

Failed Castle ActiveRecord TransactionScope causes future queries to be invalid

I am trying to solve an issue when using a Castle ActiveRecord TransactionScope which is rolled back.
After the rollback, I am unable to query the Dog table. The "Dog.FindFirst()" line fails with "Could not perform SlicedFindAll for Dog", because it cannot insert dogMissingName.
using (new SessionScope())
{
try
{
var trans = new TransactionScope(TransactionMode.New, OnDispose.Commit);
try
{
var dog = new Dog
{
Name = "Snowy"
};
dog.Save();
var dogMissingName = new Dog();
dogMissingName.Save();
}
catch (Exception)
{
trans.VoteRollBack();
throw;
}
finally
{
trans.Dispose();
}
}
catch (Exception ex)
{
var dogFromDatabase = Dog.FindFirst();
Console.WriteLine("A dog: " + dogFromDatabase.Name);
}
}
Stacktrace is as follows:
Castle.ActiveRecord.Framework.ActiveRecordException: Could not perform SlicedFindAll for Dog ---> NHibernate.Exceptions.GenericADOException: could not insert: [Mvno.Dal.Dog#219e86fa-1081-490a-92d1-9d480171fcfd][SQL: INSERT INTO Dog (Name, Id) VALUES (?, ?)] ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'Name', table 'Dog'; column does not allow nulls. INSERT fails.
The statement has been terminated.
ved System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
ved System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
ved System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
ved System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
ved System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
ved System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
ved System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
ved System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
ved System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
ved NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
ved NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation)
ved NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session)
--- End of inner exception stack trace ---
ved NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session)
ved NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session)
ved NHibernate.Action.EntityInsertAction.Execute()
ved NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
ved NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
ved NHibernate.Engine.ActionQueue.ExecuteActions()
ved NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
ved NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event)
ved NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet`1 querySpaces)
ved NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results)
ved NHibernate.Impl.CriteriaImpl.List(IList results)
ved NHibernate.Impl.CriteriaImpl.List()
ved Castle.ActiveRecord.ActiveRecordBase.SlicedFindAll(Type targetType, Int32 firstResult, Int32 maxResults, Order[] orders, ICriterion[] criteria)
--- End of inner exception stack trace ---
ved Castle.ActiveRecord.ActiveRecordBase.SlicedFindAll(Type targetType, Int32 firstResult, Int32 maxResults, Order[] orders, ICriterion[] criteria)
ved Castle.ActiveRecord.ActiveRecordBase.FindFirst(Type targetType, Order[] orders, ICriterion[] criteria)
ved Castle.ActiveRecord.ActiveRecordBase.FindFirst(Type targetType, ICriterion[] criteria)
ved Castle.ActiveRecord.ActiveRecordBase`1.FindFirst(ICriterion[] criteria)
If you look at the stack trace, you'll realize that the invalid dogMissingName record is still hanging around in the session's batched insertion buffer, even after the first attempt to perform the insertion failed. Calling Dog.FindFirst() later in the same session re-triggers an internal Flush() (which attempts once again the failed insert.)
From section 9.6 of the documentation:
From time to time the ISession will
execute the SQL statements needed to
synchronize the ADO.NET connection's
state with the state of objects held
in memory. This process, flush, occurs
by default at the following points
from some invocations of Find() or Enumerable()
from NHibernate.ITransaction.Commit()
from ISession.Flush()
Additionally, from section 9.7.2 of the documentation:
If you rollback the transaction you should immediately close and discard the current session
to ensure that NHibernate's internal state is consistent.
Simply moving using (new SessionScope()) inside the outermost try/catch may be a viable workaround (the initial insertion will fail, raise an exception which will take you out of the SessionScope, likely triggering a second failure on the same insert, failure which you finally catch -- also see "data is not flushed on SessionScope.Flush()" in com.googlegroups.castle-project-users.).
Alternatively, if you don't want to close the session, you should be able to simply change the session default flush behaviour (see the FlushMode class) so that it never flushes unless Flush() is called explicitly (e.g. before committing.) Note that managing flushing in this way will get complex and error-prone very quickly, though.
The key is right on Vlad's answer:
If you rollback the transaction you
should immediately close and discard
the current session to ensure that
NHibernate's internal state is
consistent.
After you understand and apply that, your code should then look like this:
try
{
using (new SessionScope())
using (var trans = new TransactionScope(TransactionMode.New, OnDispose.Commit))
{
try
{
var dog = new Dog { Name = "Snowy" };
dog.Save();
var dogMissingName = new Dog();
dogMissingName.Save();
}
catch (Exception)
{
trans.VoteRollBack();
throw;
}
}
}
catch (Exception ex)
{
using (new SessionScope())
{
var dogFromDatabase = Dog.FindFirst();
Console.WriteLine("A dog: " + dogFromDatabase.Name);
}
}