Isession +Nhibernate (no Session or Session was closed)

Asked

Viewed 656 times

0

In a Windowsforms project

Using Repospository pattern, in a Generic class I have the following method:

    public IList<T> Listar() {
        using (ISession session = SessionFactory.Instance.GetSession()) {
            return (from c in session.Query<T>() select c).ToList();
        }
    }

It works normally and closes Session(I imagine it’s the right way).

I load the result into a datagridview and when trying to access more complex objects (with reference to other classes) I get Exception no session or session was closed, because I’m using Lazyload by default.

Is there any way around this problem by considering keeping Lazyload?

Singleton from Sessionfactory, who always returns a new Ssion

public class SessionFactory {
    public string ConnectionString { get; set; }

    /// <summary>
    /// Instancia da classe SessionFactory
    /// </summary>
    private static SessionFactory _instance;
    private SessionFactory() {
    }
    public static SessionFactory Instance {
        get {
            return _instance ?? (_instance = new SessionFactory());
        }
    }

    /// <summary>
    /// Instancia singleton de objeto do tipo ISessionFactroy
    /// </summary>
    private ISessionFactory _sessionFactory;
    private ISessionFactory GetSessionFactory {
        get {
            return _sessionFactory ?? (_sessionFactory = BuildFactory());
        }
    }

    /// <summary>
    /// Método que retorna objeto ISessionFactory
    /// </summary>
    /// <returns></returns>
    private ISessionFactory BuildFactory() {
        try {
            IPersistenceConfigurer configDB = PostgreSQLConfiguration
                    .PostgreSQL82
                    .ConnectionString(ConnectionString)
                    .ShowSql()
                    .FormatSql()
                    .UseReflectionOptimizer();

            FluentConfiguration FConf = Fluently.Configure()
                .Database(configDB)
                .Mappings(c => c.FluentMappings.AddFromAssemblyOf<System.Retaguarda.Map.UsuarioMap>())
                .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true));

            return FConf.BuildSessionFactory();
        } catch (Exception ex) {
            Console.WriteLine("Erro ao carregar configurações do banco de dados\nDica: Verifique as configurações de conexão\n" + ex.Message + "\n" + ex.InnerException);
            throw ex;
        }
    }

    public ISession GetSession() {
        return GetSessionFactory.OpenSession();
    }

}
  • I’ve been reading around that maybe Ninject can manage Ssion and solve this problem, just haven’t found how this is possible

  • If you take the using what happens?

  • Then I would have to start Séssion at the class instance, which would keep it open causing other problems, like the same object in two different Séssion (I’ve caught enough rsrs)

  • depends ... now that I’ve seen that we’re talking about form this should be put in better understanding tag. If you can run Dispose after the grid line for example! boy depends!

  • SessionFactory.Instance that’s a singleton? put your whole class!

  • opa, added Sessionfactory, she is a Singleton, but always returns a new Isession. ?

  • You intend to use LazyLoading without having a Session open?

  • opa, added Sessionfactory, she is a singleton, but always returns a new Isession then he’s not singleton Singleton assures me an instance of a class. I would work with instances and when the form is closed give a dispose, close. I could even work with Singleton ISession in your project using it in Rfms. There are a few ways to implement this will all depend on the context

  • So, with the direct open Séssion (Singleton) works perfectly Lazyloading, but if I do a search and load the grid, it gets the loaded objects... (if at that time someone changes some information on another machine in the database) As much as I search again, it doesn’t update the information on my grid, unless I close the Session and open again

Show 4 more comments

1 answer

0


I used the Idisposable interface and I am controlling the Session in the form:

Repository:

public class Repository<T> : IDisposable, IRepository<T> where T : class {
    protected ISession session = SessionFactory.Instance.GetSession();

    public void Gravar(T entidade) {
        using (ITransaction transacao = session.BeginTransaction()) {
        }
    }

    public void Excluir(T entidade) {
        using (ITransaction transacao = session.BeginTransaction()) {
        }
    }

    public T PesquisarPorId(int Id) {
        return session.Get<T>(Id);
    }

    public IList<T> Listar() {
        return (from c in session.Query<T>() select c).ToList();
    }

    public void Dispose() {
        session.Close();
    }
}

Form:

    private void PanelCrud_Disposed(object sender, EventArgs e) {
        IDisposable disposable = Repositorio as IDisposable;
        if (disposable != null)
            disposable.Dispose();
    }

In this way, I have a Sessionfactory Singleton and for each start form a Session that will be closed in the Dispose event()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.