c# – Error returning list with Fluent NHibernate

Question:

Inside the Web.API project, I created a Get() method which returns a list of objects – IList. This AccessPerson class has a Log list (1:N).

When executing the Get() method, an exception occurs:

<ExceptionType>System.InvalidOperationException</ExceptionType>
<ExceptionType>NHibernate.LazyInitializationException</ExceptionType>
<ExceptionMessage>Initializing[RemyWebModel.Entidades.PessoaAcesso#1]-failed to lazily initialize a collection of role: RemyWebModel.Entidades.PessoaAcesso.Logs, no session or session was closed</ExceptionMessage>

Método Get():

    [HttpGet]
    public HttpResponseMessage Getall()
    {
        IList<PessoaAcesso> pessoasAcesso;

        using (var session = NHSessionFactoryManager.GetSessionFactory().OpenSession())
        {
            pessoasAcesso = session.QueryOver<PessoaAcesso>().List();
        }

        return Request.CreateResponse(HttpStatusCode.OK, pessoasAcesso, new JsonMediaTypeFormatter());
    }

Person Class Access:

public class PessoaAcesso : Pessoa
{
    [DataType(DataType.Text)]
    [Display(Name = "Login de acesso")]
    [RegularExpression(@"[a-zA-Z]{5,15}", ErrorMessage = "Login deve possuir somente letras e conter entre 5 a 15 caractéres!")]
    [Required(ErrorMessage = "O login deve ser preenchido!")]
    public virtual string Login { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Senha de acesso")]
    [MinLength(5)]
    [Required(ErrorMessage = "A senha deve ser informada!")]
    public virtual string Senha { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Cofirme novamente a senha")]
    [MinLength(5)]
    [Compare("Senha", ErrorMessage = "As senhas não conferem!")]
    public virtual string ConfirmarSenha { get; set; }

    [Display(Name = "Acesso Administrador?")]
    public virtual bool Administrador { get; set; }

    [Display(Name = "Acesso liberado?")]
    public virtual bool AcessoLiberado { get; set; }

    [Display(Name = "Perfil")]
    public virtual PermissaoPerfil Perfil { get; set; }

    public virtual IList<Log> Logs { get; set; }

    public PessoaAcesso()
    {
        Logs = new List<Log>();
    }
}

Log class:

public class Log
{
    public virtual int Id { get; protected set; }

    public virtual PessoaAcesso PessoaAcesso { get; set; }

    [DataType(DataType.DateTime)]
    [Display(Name = "Data/Hora")]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy - hh:mm:ss}")]
    public virtual DateTime DataHora { get; set; }

    [Display(Name = "Ação")]
    public virtual LogAcao Acao { get; set; }

    [DataType(DataType.Text)]
    [Display(Name = "Descrição")]
    [Required(ErrorMessage = "Descrição precisa ser preenchida!")]
    public virtual string Descricao { get; set; }
}

PersonAccess Mapping:

public class PessoaAcessoMap : SubclassMap<PessoaAcesso>
{
    public PessoaAcessoMap()
    {
        KeyColumn("Id_Pessoa");

        Map(x => x.Login)
            .Not.Nullable()
            .Length(MapLength.TextoCurto);

        Map(x => x.Senha)
            .Not.Nullable()
            .Length(MapLength.Texto);

        Map(x => x.Administrador)
            .Not.Nullable();

        Map(x => x.AcessoLiberado)
            .Not.Nullable();

        References(x => x.Perfil)
            .Column("Id_PermissaoPerfil");

        HasMany(x => x.Logs)
            .KeyColumn("Id_PessoaAcesso")
            .Cascade.All();
    }
}

As I understand it couldn't load the children "Log" because the session is closed, I just don't understand where I'm going wrong. Why does this error occur?

Answer:

The problem was in the session block:

using (var session = NHSessionFactoryManager.GetSessionFactory().OpenSession())

In this case, I need to leave the session open so that the result can be completely delivered, in the case of child records – Log.

Therefore, I removed the use of using leaving the session variable open:

public IEnumerable<PessoaAcesso> GetAll()
{
        var session = NHSessionFactoryManager.GetSessionFactory().OpenSession();

        return session
            .CreateCriteria(typeof(PessoaAcesso))
            .List<PessoaAcesso>();
}
Scroll to Top