Разница между Nhibernate Session.Get и Session.CreateCriteria

В чем разница между Nhibernate Session.Get и Session.CreateCriteria?

Моя история такова:

В нашем продукте мы реализовали softDeletion, добавив интерфейс ISoftDeletable, у каждого класса, который реализует этот интерфейс, есть поля deleteDate и deleteBy. Также у нас есть класс AuditableEntity, который означает, что у каждого класса, который его реализует, есть: creationDate, creationBy,ifiedDate,ifiedBy.

Вот источники:

public class SaveUpdateEventListener : DefaultSaveEventListener
{

    private readonly ISecurityContextService securityContextService;

    public SaveUpdateEventListener(ISecurityContextService securityContextService)
    {
        this.securityContextService = securityContextService;
    }

    protected override object PerformSaveOrUpdate(SaveOrUpdateEvent @event)
    {
        this.PrepareAuditableEntity(@event);
        return base.PerformSaveOrUpdate(@event);
    }


    private void PrepareAuditableEntity(SaveOrUpdateEvent @event)
    {
        var entity = @event.Entity as AuditableEntity;

        if (entity == null)
        {
            return;
        }

        if (this.securityContextService.EdiPrincipal == null)
        {
            throw new Exception("No logged user.");
        } 

        if (entity.Id == 0)
        {
            this.ProcessEntityForInsert(entity);
        }
        else
        {
            this.ProcessEntityForUpdate(entity);
        }
    }


    private void ProcessEntityForUpdate(AuditableEntity entity)
    {
        entity.ModifiedBy = securityContextService.GetLoggedUser();
        entity.ModifiedDate = DateTime.Now;
    }


    private void ProcessEntityForInsert(AuditableEntity entity)
    {
        entity.CreatedBy = securityContextService.GetLoggedUser();
        entity.CreatedDate = DateTime.Now;
    }

Также мы переопределили метод Session.Get.

public virtual T Get(long id)
    {
        if (typeof(ISoftDeletable).IsAssignableFrom(typeof(T)))
        {
            return
                this.Session.CreateCriteria(typeof(T))
                .Add(Restrictions.Eq("Id", id))
                //.Add(Restrictions.IsNull("DeletedDate"))
                .UniqueResult<T>();
        }

        return Session.Get<T>(id);
    }

Теперь в некотором контексте приложение сгенерировало исключение Stackru в методах Get для объекта softDeletable и Auditable. После некоторого исследования я заметил, что он создает цикл между PrepareEntityForUpdate/securityContextService.GetLoggedUser и методом Get из нашего пользовательского репозитория. Как вы можете заметить, я прокомментировал ограничение на DeletedDate, это означает, что Session.Get(id) должен возвращать тот же результат, что и созданные критерии. Но если я пойду через this.Session.CreateCriteria(typeof(T)), я получу исключение Stackru, если я прокомментирую это и оставлю только return Session.Get(id) (без учета deletetiondate), все работает нормально.

Это заставляет меня думать, что Session.Get и Session.CreateCriteria работают по-разному. Есть идеи?

2 ответа

Решение

Get будет использовать кеш сессии. Критерии не будут.

Другими словами: критерии всегда приводят к SQL-запросу / обращению к БД. Get не всегда приводит к SQL-запросу. Если сущность уже была загружена NHibernate в сеансе, и вы хотите снова извлечь сущность, используя Get, NHibernate вернет сущность, которую он уже загрузил, из своего кеша.

В дополнение к этому вы можете установить, где параметр в классе отображения. Там вы можете добавить: "DeletedDate IS NULL". Когда Get выполняется NHibernate, добавьте этот оператор WHERE в сгенерированный запрос.

Другие вопросы по тегам