Сбой NHibernate при вызове из веб-элемента управления в ASP.Net - PullRequest
1 голос
/ 28 января 2009

У меня очень странная проблема: происходит сбой NHibernate при вызове из веб-элемента управления.

Я работаю над веб-страницей ASP.Net (2.0), которая использует NHibernate для доступа к базе данных.

И у меня есть простой фабричный класс для доступа к столбцу CurrentStepNumber в таблице ProjectInfo:

public class ProjectEntity
{
    private int? _currentStepNumber;
    public virtual int? CurrentStepNumber
    {
        get { return _currentStepNumber; }
        set { _currentStepNumber = value; }
    }

    public static ProjectWizardEntity GetById(int id, bool shouldLock) 
    {
        return RepositoryFactory.ProjectWizardRepository.GetById(id, shouldLock);
    }

    public static ProjectWizardEntity GetById(int id) 
    {
        return GetById(id, false);
    }

    public virtual void Save() 
    {
        RepositoryFactory.ProjectWizardRepository.Save(this);
    }

    public virtual void SaveOrUpdate() 
    {   
        RepositoryFactory.ProjectWizardRepository.SaveOrUpdate(this);
    }
}

Доступ к этому классу осуществляется через прокси-класс, поэтому при каждом назначении нового значения оно сбрасывается в базу данных:

public class DBHelper
{
ProjectEntity _projectEntity;
ProjectEntity GetProjectEntity()
{
    if (_projectEntity == null)
        _projectEntity = //get or create a new one;

    return _projectEntity ;
}

public int? CurrentStepNumber
{
    get
    {
        return (CurrentProjectId > 0) ? CurrentProjectWizardEntity.CurrentStepNumber : 0;
    }
    set
    {
        if (CurrentProjectId > 0)
        {

            CurrentProjectWizardEntity.CurrentStepNumber = value;
            CurrentProjectWizardEntity.SaveOrUpdate();
        }
    }
}
}

Теперь проблема:

  1. Когда я получаю доступ к CurrentStepNumber со страницы test.aspx, все отлично работает
  2. Когда я читаю это поле из пользовательского веб-элемента управления (test.ascx), который используется на странице test.aspx, все еще в порядке
  3. Однако , когда я пытаюсь присвоить значение CurrentStepNumber в коде элемента управления (test.ascx), я всегда получаю исключение:

NHibernate.NonUniqueObjectException: другой объект с тем же значением идентификатора уже был связан с сеансом

На самом деле SaveOrUpdate метод репозитория NHibernate вызывает исключение.

Я не мог понять, в чем здесь проблема, поэтому любая помощь будет оценена.

1 Ответ

0 голосов
/ 01 сентября 2010

Я думаю, что у вас есть проблема управления сеансом здесь. Как RepositoryFactory.ProjectWizardRepository.GetById создает и, возможно, удаляет сеанс NHibernate? Создает ли, а затем закрывает сеанс?

Похоже, что DBHelper.GetProjectEntity () создает или загружает ProjectEntity. Позже, когда я вызвал сеттер CurrentStepNumber, вы вставляете или обновляете объект в базе данных.

Проблема в том, что когда DBHelper.GetProjectEntity () загружает существующий объект и затем закрывает сессию после того, как он был загружен, но держит объект рядом, мы попадаем в глубокую воду. Когда объект позднее обновляется, вы устанавливаете новое значение для CurrentStepNumber и отправляете объект в NHibernate для сохранения. Проблема здесь в том, что объект не связан с новым сеансом, который создается и закрывается во время сохранения. Затем Nhibernate запутывается, так как обнаружен новый объект, который не загружается из текущего сеанса, но имеет идентификатор существующего объекта.

В качестве решения, Google для «управления сессиями NHibernate asp.net», и вы получите множество хороших отзывов о том, как использовать цикл запросов ASP.NET в качестве единицы работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...