protected virtual void Update(object id, object[] fields, object[] oldFields, bool[] includeProperty, object oldVersion, object obj, SqlString sqlUpdateString, ISessionImplementor session)
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("Updating entity: " + MessageHelper.InfoString(this, id));
                if (IsVersioned)
                {
                    log.Debug("Existing version: " + oldVersion + " -> New Version: " + fields[VersionProperty]);
                }
            }

            if (!hasUpdateableColumns)
            {
                return;
            }

            try
            {
                IDbCommand statement = IsBatchable ?
                                       session.Batcher.PrepareBatchCommand(sqlUpdateString) :
                                       session.Batcher.PrepareCommand(sqlUpdateString);

                try
                {
                    // now write the values of fields onto the command

                    int index = Dehydrate(id, fields, includeProperty, statement, session);

                    // Write any appropriate versioning conditional parameters
                    if (IsVersioned && OptimisticLockMode == OptimisticLockMode.Version)
                    {
                        VersionType.NullSafeSet(statement, oldVersion, index, session);
                    }
                    else if (OptimisticLockMode.Version < OptimisticLockMode && null != oldFields)
                    {
                        bool[] includeOldField = OptimisticLockMode == OptimisticLockMode.All ?
                                                 PropertyUpdateability :
                                                 includeProperty;

                        for (int j = 0; j < HydrateSpan; j++)
                        {
                            if (includeOldField[j] && oldFields[j] != null)
                            {
                                PropertyTypes[j].NullSafeSet(statement, oldFields[j], index, session);
                                index += propertyColumnSpans[j];
                            }
                        }
                    }

                    if (IsBatchable)
                    {
                        session.Batcher.AddToBatch(1);
                    }
                    else
                    {
                        Check(session.Batcher.ExecuteNonQuery(statement), id);
                    }
                }
                catch (Exception e)
                {
                    if (IsBatchable)
                    {
                        session.Batcher.AbortBatch(e);
                    }

                    throw;
                }
                finally
                {
                    if (!IsBatchable)
                    {
                        session.Batcher.CloseCommand(statement, null);
                    }
                }
            }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw Convert(sqle, "could not update: " + MessageHelper.InfoString(this, id));
            }
        }
        /// <summary>
        /// Delete an object
        /// </summary>
        /// <param name="id">The id of the object to delete.</param>
        /// <param name="version">The version of the object to delete.</param>
        /// <param name="obj">The object to delete.</param>
        /// <param name="session">The session to perform the deletion in.</param>
        public override void Delete(object id, object version, object obj, ISessionImplementor session)
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("Deleting entity: " + MessageHelper.InfoString(this, id));
                if (IsVersioned)
                {
                    log.Debug("Version: " + version);
                }
            }

            try
            {
                IDbCommand deleteCmd;

                if (IsVersioned)
                {
                    deleteCmd = session.Batcher.PrepareCommand(SqlDeleteString);
                }
                else
                {
                    deleteCmd = session.Batcher.PrepareBatchCommand(SqlDeleteString);
                }


                try
                {
                    // Do the key.  The key is immutable so we can use the _current_ object state - not necessarily
                    // the state at the time the delete was issued.
                    IdentifierType.NullSafeSet(deleteCmd, id, 0, session);

                    // we should use the _current_ object state (ie. after any updates that occurred during flush)
                    if (IsVersioned)
                    {
                        VersionType.NullSafeSet(deleteCmd, version, IdentifierColumnNames.Length, session);
                        Check(session.Batcher.ExecuteNonQuery(deleteCmd), id);
                    }
                    else
                    {
                        session.Batcher.AddToBatch(1);
                    }
                }
                catch (Exception e)
                {
                    if (!IsVersioned)
                    {
                        session.Batcher.AbortBatch(e);
                    }
                    throw;
                }
                finally
                {
                    if (IsVersioned)
                    {
                        session.Batcher.CloseCommand(deleteCmd, null);
                    }
                }
            }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw Convert(sqle, "could not delete: " + MessageHelper.InfoString(this, id));
            }
        }