C # NHibernate с Spring LazyInitializationException при использовании данных - PullRequest
2 голосов
/ 08 декабря 2010

Я работаю над проектом NHibernate, и там, где раньше у меня были проблемы с загрузкой коллекций (http://stackoverflow.com/questions/4213506/c-hibernate-criteria-loading-collection), У меня сейчас проблемы с использованием данных.

Я использую C # в сочетании с NHibernate и Spring.Net Framework, и я получаю LazyInitializationException после того, как я загружаю, например, 'ordercredit', а затем получаю доступ к объекту ordercredit.

Я использую этот код для получения OrderCredit:

OrderCredit oc = CreditService.getOrderCredit(ordercredit.Id);

Код, который я использую для загрузки, выполняется с использованием реализации DAO:

[Transaction(TransactionPropagation.Required, ReadOnly = true)]
public OrderCredit GetOrderCredit(long ordercreditid)
{
    var creditrules = Session.CreateCriteria(typeof(OrderCredit));
    creditrules.Add(Restrictions.Eq("Id", ordercreditid));
    return creditrules.List<OrderCredit>()[0];
}

Когда я запускаю это на своей локальной машине, все работает нормально, и я фактически намеревался загрузить список этих 'ordercredits',но это также пошло не так, поэтому я сначала попытался сделать более простой шаг.

Объекты внутри OrderCredit определены как [OneToMany].

Когда я помещаю это на тестовый сервер, ипопытаться получить доступ к объекту 'OrderObject' загруженного OrderCredit, я получаю ошибку:

NHibernate.LazyInitializationException: Initializing [.OrderObject # 5496522] -CoВы не можете инициализировать прокси - нет сеанса.

Код, который не работает:

Log.Debug(oc.OrderObject.Name);

Код, который работает:

Log.Debug(oc.Id);

Это происходит для любого объекта, который является частью OrderCredit, но я могу получить доступ к полям свойств OrderCredit (например, OrderCredit.Id).

Кроме того, когда я получаю доступ к любому из объектов ДО, я возвращаю данные в исходную функцию, вызывающую метод,затем он кеширует информацию или около того, так как я могу получить к ней доступ.

Я много читал об этой проблеме, например, отключение Lazy, но у меня это тоже не сработало (или я это сделалне в том месте).

Больше всего меня расстраивает то, что он действительно работает на моей локальной машине, а не на тест-сервере.Что я могу делать не так?

Любая помощь высоко ценится.

1-е обновление:

Я сейчас использую GenericDao, используя метод загрузки 1 ордера по умолчанию по умолчанию.Я использую следующий код для загрузки 1 ordercredit по Id.

OrderCredit oc = GenericService.Load<OrderCredit>(Id);

Код, который находится внутри GenericDAO, следующий, НО он не завершает или не прерывает сеанс, что означает, что я могу получить доступ к объектамприкреплен к заказу:

[Transaction(TransactionPropagation.Supports, ReadOnly = true)]
public T Load<T>(long id) where T : ISaveableObject
{
    var obj = Session.Load<T>(id);
    return obj;
}

Это почти тот же код, который был у меня в функции, которую я включил ранее в этом вопросе.

Теперь я действительно сбит с толку, потому что я нене знаю, что это может быть, что заканчивает сессию.Я буду работать с ним сейчас, так как он работает, но я хочу изменить его позже, чтобы я мог использовать свою функцию для вызова всей коллекции и доступа к ним через каждый цикл.

В настоящее время я использую свойФункция 'getOrderCredits', чтобы получить список объектов OrderCredit, и в foreach я получаю Id, и использую GenericDao.Load, чтобы получить фактический элемент, и могу получить доступ к объектам и тому подобное.Конечно, это не так, как должно быть и должно быть.

Я был бы удивлен, если бы я решил это.

1 Ответ

4 голосов
/ 03 марта 2011

Это обычная проблема, с которой сталкиваются люди при использовании NHibernate. Это происходит потому, что:

  1. Вы открываете сеанс
  2. Вы загружаете сущность из базы данных, которая ссылается на другую сущность
  3. Вы закрываете сессию
  4. Вы пытаетесь получить доступ к свойству объекта, на который указывает ссылка
  5. NHibernate пытается лениво загрузить объект из базы данных, используя тот же сеанс, который загружал родительский объект
  6. Сессия закрыта, поэтому NHibernate генерирует исключения, такие как woah.

У вас есть несколько вариантов здесь:

  1. Держите ваш сеанс открытым дольше, желательно используя что-то вроде схемы работы, что даст вам более жесткий контроль.
  2. С готовностью загружает ваши ссылочные объекты, когда вы запрашиваете:

В вашем случае, поскольку Spring управляет вашей транзакцией для вас, второй вариант, вероятно, является самым быстрым / простым решением.

var creditrules = Session.CreateCriteria(typeof(OrderCredit));
creditrules.Add(Restrictions.Eq("Id", ordercreditid))
  .SetFetchMode("OrderObject", FetchMode.Eager);

Это загрузит OrderObject при загрузке OrderCredit.

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