У меня есть веб-служба C# .Net. Я вызываю dll (C# .Net), который использует nHibernate для подключения к моей базе данных. Когда я вызываю dll, он выполняет запрос к db и загружает родительский объект «Задача». Однако, когда длл пытается получить доступ к дочерним объектам «Task.SubTasks», он выдает следующее сообщение об ошибке:Веб-служба nHibernate SessionFactory issue
NHibernate.HibernateException failed to lazily initialize a collection of role: SubTasks no session or session was closed
Я новичок в NHibernate так что не уверен, что часть кода, я пропускаю.
Должен ли я запускать заводскую сессию в своем веб-сервисе перед вызовом dll? Если да, то как мне это сделать?
EDIT: Добавлен код веб-службы и код метода CreateContainer(). Этот код вызывается непосредственно перед вызовом DLL
[WebMethod]
public byte[] GetTaskSubtask (string subtaskId)
{
var container = CreateContainer(windsorPath);
IoC.Initialize(container);
//DLL CALL
byte[] theDoc = CommonExport.GetSubtaskDocument(subtaskId);
return theDoc;
}
/// <summary>
/// Register the IoC container.
/// </summary>
/// <param name="aWindsorConfig">The path to the windsor configuration
/// file.</param>
/// <returns>An initialized container.</returns>
protected override IWindsorContainer CreateContainer(
string aWindsorConfig)
{
//This method is a workaround. This method should not be overridden.
//This method is overridden because the CreateContainer(string) method
//in UnitOfWorkApplication instantiates a RhinoContainer instance that
//has a dependency on Binsor. At the time of writing this the Mammoth
//application did not have the libraries needed to resolve the Binsor
//dependency.
IWindsorContainer container = new RhinoContainer();
container.Register(
Component.For<IUnitOfWorkFactory>().ImplementedBy
<NHibernateUnitOfWorkFactory>());
return container;
}
EDIT: Добавление кода DLL и код хранилища ...
DLL Код
public static byte[] GetSubtaskDocument(string subtaskId)
{
BOESubtask task = taskRepo.FindBOESubtaskById(Guid.Parse(subtaskId));
foreach(subtask st in task.Subtasks) <--this is the line that throws the error
{
//do some work
}
}
Repository для задачи
/// <summary>
/// Queries the database for the Subtasks whose ID matches the
/// passed in ID.
/// </summary>
/// <param name="aTaskId">The ID to find matching Subtasks
/// for.</param>
/// <returns>The Subtasks whose ID matches the passed in
/// ID (or null).</returns>
public Task FindTaskById(Guid aTaskId)
{
var task = new Task();
using (UnitOfWork.Start())
{
task = FindOne(DetachedCriteria.For<Task>()
.Add(Restrictions.Eq("Id", aTaskId)));
UnitOfWork.Current.Flush();
}
return task;
}
Репозиторий подзадачи
/// <summary>
/// Queries the database for the Subtasks whose ID matches the
/// passed in ID.
/// </summary>
/// <param name="aBOESubtaskId">The ID to find matching Subtasks
/// for.</param>
/// <returns>The Subtasks whose ID matches the passed in
/// ID (or null).</returns>
public Subtask FindBOESubtaskById(Guid aSubtaskId)
{
var subtask = new Subtask();
using (UnitOfWork.Start())
{
subtask = FindOne(DetachedCriteria.For<Subtask>()
.Add(Restrictions.Eq("Id", aSubtaskId)));
UnitOfWork.Current.Flush();
}
return subtask;
}
благодарит за отзыв. Но, думаю, моя проблема на более высоком уровне. У меня нет кода сеанса nHibernate. Я открываю контейнер с помощью Windsor, но не сеанс. Код, который бросает ошибку, находится в самой dll. Веб-служба инициализирует контейнер, а затем вызывает DLL. Dll захватывает объекты из db и возвращает их в качестве байта [] в веб-службу, но до тех пор, пока она не попадет туда. – MikeTWebb
, но в какой-то момент кто-то открывает и закрывает сеанс NHibernate. И поскольку ошибка говорит о том, что NHibernate жалуется на закрытую сессию, ее, должно быть, кто-то открыл и закрыл. Какие части Виндзора вы используете? ActiveRecord, WCF Facility, NHibernate Integration? –
согласился ... это происходит «автоматически» где-то. И это nHibernate Integration. В hibernate.cfg есть раздел для. Я добавил код CreateContainer выше –
MikeTWebb