views:

26

answers:

1

Normally the parameterized SQL works great for CRUD, but I have one instance where I want to use a stored procedure to do an insert.

My HBM file has the following (along with a bunch of other properties, bags, etc)

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MyProject.Entities" assembly="MyProject">
  <class name="MyProject.Entities.Policy, MyProject" table="dbo.Policy" lazy="true">
    <id name="Id" column="[PolicyId]">
      <generator class="native" />
    </id>
    <sql-insert>exec spInsertPolicy ?,?,?,?,?,?,?</sql-insert>
  </class>
</hibernate-mapping>

The number of question marks in the sql-insert matches the number of properties and many-to-one relationships (there isn't a question mark for the Id).

I'm getting the following exception. If I switch the generator to "increment" it works, but I don't want to do that because other processes are permitted to save to the database.

NHibernate.HibernateException: The database returned no natively generated identity value
       at NHibernate.Id.IdentifierGeneratorFactory.GetGeneratedIdentity(IDataReader rs, IType type, ISessionImplementor session)
       at NHibernate.Id.IdentityGenerator.InsertSelectDelegate.ExecuteAndExtract(IDbCommand insert, ISessionImplementor session)
       at NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
       at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session)
       at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session)
       at NHibernate.Action.EntityIdentityInsertAction.Execute()
       at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
       at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)

Any suggestions? Thanks.

A: 

The stored procedure has to return the generated ID for the inserted record, i.e. a SELECT SCOPE_IDENTITY() at the end of the sproc if you're using SQL Server.

Mauricio Scheffer
I assumed that would be called automatically by NHibernate after executing the stored procedure.You rock!
Eric