Vencovsky
Vencovsky

Reputation: 31713

NHibernate don't persists with session.Save and transaction.Commit

I'm trying to configure NHibernate on .net core but still no sucess.

I can read the data, but when I try to save or delete, it doesn't work.

There is too much information like how I created my services, repository and mapping, so I will skip some files in this question, but everything is avaliable at my git repo.

So I have a very simple model.

public class Book
{
    public virtual Guid Id { get; set; }
    public virtual string Title { get; set; }
}

I also created a extension method for adding nhibernate in my service

public static class NHibernateExtensions
{  

    public static IServiceCollection AddNHibernate(this IServiceCollection services, string connectionString)
    {
        var mapper = new ModelMapper();
        mapper.AddMappings(typeof(NHibernateExtensions).Assembly.ExportedTypes);
        HbmMapping domainMapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

        var configuration = new Configuration()
            .DataBaseIntegration(c =>
            {
                c.Dialect<MsSql2012Dialect>();
                c.ConnectionString = connectionString;
                c.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
                c.SchemaAction = SchemaAutoAction.Validate;
                c.LogFormattedSql = true;
                c.LogSqlInConsole = true;
            });

        configuration.AddMapping(domainMapping);
        var fluentSessionFactory = Fluently
            .Configure(configuration)
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Book>())
            .BuildSessionFactory();

        var sessionFactory = configuration.BuildSessionFactory();

        services.AddSingleton(fluentSessionFactory);
        services.AddScoped(factory => fluentSessionFactory.OpenSession());
        services.AddScoped<ISessionManager, SessionManager>();

        return services;
    }
}

Here is my StartUp

public void ConfigureServices(IServiceCollection services)
{
    var connStr = Configuration.GetConnectionString("DefaultConnection");

    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();
    services.AddNHibernate(connStr);

    services.AddTransient<IBookRepository, BookRepository>();
    services.AddTransient<IBookService, BookService>();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
}

And I created a BaseRepository for handle simple repository actions.

The problem I'm having is that in BaseRepository, when I call Add, it doesn't persists in the database.

public void Delete(T entity){
    using (var transaction = Session.BeginTransaction())
    {
        Session.Delete(entity);                
        transaction.Commit();
        Session.Flush();
    }
}

When I call Queryable.ToList(), I get everything as expected.

What I'm doing wrong on the configurations that it doesn't persists in the db?

Observation: The database is SQL Server 2017 and is running on a docker container.

Upvotes: 0

Views: 932

Answers (1)

Roman Artiukhin
Roman Artiukhin

Reputation: 2367

That's because you open new session on each Session access:

protected ISession Session => SessionFactory.OpenSession();

Transaction is started in one session add/delete in other flush in third. Obviously you need to do all operations in one session.

Also you don't need to call Flush by default - it should be called automatically on transaction.Commit. And if you really need to call Flush - do it before transaction commit.

Upvotes: 2

Related Questions