1
votes

Overriding DefaultDeleteEventListener and DefaultLoadEventListener provided a really good solution to implement soft deletables using Nhibernate.

 public class SoftDeletableLoadEventListener : DefaultLoadEventListener
    {
        #region Non-public members

        protected override object DoLoad(LoadEvent @event,
            IEntityPersister persister, EntityKey keyToLoad,
            LoadType options)
        {
            object entity = base.DoLoad(@event, persister, keyToLoad, options);

            var softEntity = entity as ISoftDeletable;

            if (softEntity != null && softEntity.IsDeleted)
            {
                if (options == LoadEventListener.ImmediateLoad
                    || options == LoadEventListener.Load)
                {
                    string msg =
                        string.Format("Can not Load soft deleted entity typeof({0}) with Id {1} as it was deleted.",
                            softEntity.GetType().Name,
                            softEntity.Id);

                    throw new InvalidOperationException(msg);
                }
            }

            return entity;
        }

        #endregion
    }

As the summary for DefaultLoadEventListener states: Defines the default load event listeners used by NHibernate for loading entities in response to generated load events.

This means that when doing ExtraLazyLoading the filter is not applied which results in e.g.: Deleted entities being count. Is there another way to apply soft deletable filters during queries? Are there better ways then always filtering adding restriction manually?

1

1 Answers

2
votes

I've implemented soft-deletes with nh without overriding the DefaultLoadEventListener, but I think my collection load strategy could help you as well. You can add a where clause specification to your collections :

Fluent NHibernate

.Override<Parent>(map =>
{
    map.HasMany<Child>(p => p.Children)
        .Where("IsDeleted = 0");
})

HBM.xml

<bag name="Children" where="IsDeleted = 0">
  <key>
    <column name="ParentID" />
  </key>
  <one-to-many class="Child" />
</bag>

edit Just found this link about soft deletes from nhibernate.info which recommends using the overridden DefaultLoadEventListener and filtering the selects using the where clause specification.