Answer first
NHibernate does not validate the connection string or open a physical database connection during ISessionFactory.BuildSessionFactory(). The factory is built successfully even with an invalid string; a connection is opened lazily when the first ISession is created or when schema export runs. Therefore an incorrect connection string is only discovered at runtime, not at factory build time.
Confirmed facts
- NHibernate supports SQLite via
NHibernate.Driver.SQLite20Driver and NHibernate.Dialect.SQLiteDialect. The SessionFactory is thread‑safe and expensive to create.
- SQLite in‑memory databases exist only for the lifetime of the connection that created them. With the default driver each new NHibernate connection gets a new empty database unless
cache=shared is used or a single ADO.NET connection is kept open for the fixture.
SchemaExport (or SchemaUpdate) opens a connection and will fail fast if the connection string is wrong, providing an early‑validation point.
Likely explanation
Because the connection is opened lazily, tests that rely on the factory build succeeding may still encounter empty tables or connection errors when the first session is opened. Keeping one open ADO.NET connection for the fixture lifetime and reusing it for schema export and sessions makes the in‑memory database visible to all sessions in that fixture.
Steps for this case
- Create a test‑only configuration that points to an in‑memory SQLite database, disables production settings, and specifies the SQLite driver and dialect.
var cfg = new NHibernate.Cfg.Configuration()
.DataBaseIntegration(db => {
db.Dialect();
db.Driver();
db.ConnectionString = \"Data Source=:memory:;Version=3;New=True;\";
db.ConnectionReleaseMode = NHibernate.Connection.ConnectionReleaseMode.OnClose;
db.IsolationLevel = System.Data.IsolationLevel.ReadCommitted;
})
.AddAssembly(typeof(YourEntity).Assembly);
- Build the factory once per fixture and force early validation by opening a connection or running schema export immediately.
var factory = cfg.BuildSessionFactory();
// Option A: test connection
using var testSession = factory.OpenSession();
testSession.CreateSQLQuery(\"SELECT 1\").UniqueResult();
// Option B: schema export
new NHibernate.Tool.hbm2ddl.SchemaExport(cfg).Create(false, true);
- Export the schema from mappings before opening any test sessions, then use sessions from that factory for the test.
using var schemaSession = factory.OpenSession();
using var tx = schemaSession.BeginTransaction();
// schema already exported; tx can be committed or rolled back as needed
tx.Commit();
- Dispose the factory after fixture teardown. Ensure no production
hibernate.cfg.xml or app settings are referenced in the test build.
Verification
- Log the configured connection string after the factory is built and assert it contains
:memory: and no production host or credentials.
- Save an entity in one session and query it in a second session from the same factory to confirm the in‑memory DB is shared for the fixture.
- Monitor that no production connection is opened during the test run (e.g., via a debugger or connection‑string listener).
One diagnostic detail that changes the recommendation: which SQLite ADO.NET provider you are using (e.g., System.Data.SQLite vs Microsoft.Data.Sqlite) because the connection string format and driver class differ, affecting the exact keep‑alive pattern for :memory:.