2010-12-08 2 views
2

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

Я использую C# в сочетании с базой NHibernate и Spring.Net, и я получаю исключение 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].

Когда я положил это на TestServer, и попытаться получить доступ к объекту «OrderObject» загруженного OrderCredit, я получаю ошибку:

NHibernate.LazyInitializationException: Инициализация [.OrderObject # 5496522] не инициализирует -Не могли бы прокси - нет сеанса.

код, который не удается:

Log.Debug(oc.OrderObject.Name); 

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

Log.Debug(oc.Id); 

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

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

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

Вещь, которая меня больше всего расстраивает, заключается в том, что она действительно работает на моей локальной машине, а не на тестовом сервере. Что я могу делать неправильно?

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

первое обновление:

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

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

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

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

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

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

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

Я был бы поражен, если я это разрешу.

+0

Где вы открываете и закрываете сеанс NH? Это сообщение об ошибке указывает на то, что сеанс NH был закрыт к моменту попытки ленивой загрузки. – 2010-12-08 13:12:30

+0

Это расширение, которое я делаю из рабочего проекта. Сделки обрабатываются менеджером транзакций Hibernate/Spring. Я делал разные вещи и приходил к небольшой работе. Я отредактирую свой вопрос и добавлю эту информацию и код, поскольку я просто не понимаю, что это не так в моей ситуации. – Honnes 2010-12-08 13:57:43

ответ

4

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

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

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

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

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

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

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