Saga Data Tables Not Created When using NHibernate Persistence

392 views
Skip to first unread message

Jesse Inskeep

unread,
May 13, 2015, 11:46:10 AM5/13/15
to particula...@googlegroups.com
I am working on a POC of using NHibernate as our persistence layer instead of RavenDB.

I am running into a problem with using NHibernate for our persistence layer with relation to sagas. When the message is being received by the saga, I get the following error message:

could not execute query
[ SELECT this_.Id as Id0_0_, this_.Originator as Originator0_0_, this_.OriginalMessageId as Original3_0_0_, this_.OrderNumber as OrderNum1_1_0_, this_.Order as Order1_0_, this_._OrderNumber as column3_1_0_, this_._Order as column4_1_0_ FROM OrderPolicyData this_ with (updlock, rowlock) WHERE this_.OrderNumber = @p0 ]
  Name:cp0 - Value:12
[SQL: SELECT this_.Id as Id0_0_, this_.Originator as Originator0_0_, this_.OriginalMessageId as Original3_0_0_, this_.OrderNumber as OrderNum1_1_0_, this_.Order as Order1_0_, this_._OrderNumber as column3_1_0_, this_._Order as column4_1_0_ FROM OrderPolicyData this_ with (updlock, rowlock) WHERE this_.OrderNumber = @p0]


When I got to the database, I notice that there is no table called OrderPolicyData. My assumption is that the saga tables are not being created at start up.

Now, the other persistence tables ARE being created. There is a table of "Subscription" and "TimeoutEntity", but no OrderPolicyData table (which I'm assuming would be the saga table needed).

I did notice that for NHibernate to even work I had to mark my SagaData properties as "Overridable" (the C# equivalent of virtual). This is something that I didn't have to do when using RavenDB as my persistence. I'm wondering if there are any other "gotchas" with differences between RavenDB and NHibernate.....

Here is my endpoint config:
Imports System.ConfigurationImports
Imports NServiceBus

Public Class EndpointConfig : Implements IConfigureThisEndpoint, AsA_Server
   
   
Public Sub Customize(configuration As BusConfiguration) Implements IConfigureThisEndpoint.Customize

        configuration
.UsePersistence(Of NHibernatePersistence)()

       
''disable 2nd level retries - for testing purposes
        configuration
.DisableFeature(Of Features.SecondLevelRetries)()

       
''setup unobtrusive messaging conventions
        configuration
.Conventions.DefiningCommandsAs(Function(r) r.Namespace <> Nothing And r.Namespace.EndsWith("Commands"))
        configuration
.Conventions.DefiningEventsAs(Function(r) r.Namespace <> Nothing And r.Namespace.EndsWith("Events"))
        configuration
.Conventions.DefiningMessagesAs(Function(r) r.Namespace <> Nothing And r.Namespace.EndsWith("Messages"))

   
End Sub
End Class

And here is my saga (its very trivial, just doing a test to get this working):
Imports NServiceBusImports
Imports NServiceBus.Saga

Namespace Policies
   
Public Class OrderPolicy : Inherits Saga(Of OrderPolicyData) : Implements IAmStartedByMessages(Of Contracts.Commands.StartNewOrder)

       
Protected Overloads Overrides Sub ConfigureHowToFindSaga(mapper As SagaPropertyMapper(Of OrderPolicyData))
            mapper
.ConfigureMapping(Of Contracts.Commands.StartNewOrder)(Function(r) r.OrderNumber).ToSaga(Function(r) r.OrderNumber)
       
End Sub

       
Public Sub Handle(message As Contracts.Commands.StartNewOrder) Implements IHandleMessages(Of Contracts.Commands.StartNewOrder).Handle
           
Me.Data.OrderNumber = message.OrderNumber
           
Me.Data.Order = message.Product
       
End Sub
   
End Class

   
Public Class OrderPolicyData : Inherits ContainSagaData

       
<Unique>
       
Public Overridable Property OrderNumber As String

       
Public Overridable Property Order As String

   
End Class
   
End Namespace

NServiceBus Version: 5.2.0
NServiceBus.Host Version: 6.0.0
NServiceBus.NHibernate 6.1.2


Ramon Smits

unread,
May 15, 2015, 2:44:05 PM5/15/15
to particula...@googlegroups.com


Hi Jesse,


All your properties need to be marked 'virtual' in c# and indeed Overridable in VB.net. This is a requirement by NHibernate so that it can 'inherit' the class and add its magic by overloading the properties.

Other gotcha's depend on how complex your saga classes are. If they get too complex or when when you want to use different types in the sql database then you need to create nhibernate mapping files. With these mappings NHibernate knows how it can map properties by columns as well as collections to tables and their foreign keys.

Another difference of course is RavenDB is a document store and NHibernate stores it in the configured relational database. This means that when you have a saga entity with a collection property that this property is stored in a separate table. This requires multiple roundtrips to the database to read and/or write all data where with RavenDB this is always one roundtrip.


I would recommend reading a beginners tutorial to get a feeling what NHibernate is and how it works:



NHibernate creates or updates the database schema at startup. You should not need to create any tables yourself.



Regards,
Ramon

Hrannar Jóhannsson

unread,
Jun 4, 2015, 7:08:36 AM6/4/15
to particula...@googlegroups.com
Hi Jesse, 

I ran into the same issue recently and my problem was that the database user did not have the rights to create table.

- Hrannar
Reply all
Reply to author
Forward
0 new messages