I use NHibernate for my dataacess, and for awhile not I've been using SQLite for local integration tests. I've been using a file, but I thought I would out the :memory: option. When I fire up any of the integration tests, the database seems to be created (NHibernate spits out the table creation sql) but interfacting with the database causes an error.
Has anyone every gotten NHibernate working with an in memory database? Is it even possible? The connection string I'm using is this:
Data Source=:memory:;Version=3;New=True
I am doing it with Rhino Commons. If you don't want to use Rhino Commons you can study the source do see how it does it. The only problem I have had is that SQLite does not support nested transactions. This forced me to change my code to support integration testing. Integration testing with in memory database is so awesome, I decided it was a fair compromise.
Just want to thank decates. Been trying to solve this for a couple of months now and all I had to do was add
to the connection string in my nhibernate config file. Also using just NHibernate with *.hbm.xml and not FNH and didn't really have to modify my code at all!
I was able to use a SQLite in-memory database and avoid having to rebuild the schema for each test by using SQLite's support for 'Shared Cache', which allows an in-memory database to be shared across connections.
I did the following in AssemblyInitialize (I'm using MSTest):
Configure NHibernate (Fluently) to use SQLite with the following connection string:
Use that configuration to create a hbm2ddl.SchemaExport object, and execute it on a separate connection (but with that same connection string again).
Before each test runs, a new session is created, and the test runs in a transaction which is rolled back at the end.
Here is an example of the test assembly-level code:
And a base class for each unit test class/fixture:
Resource management could improve, I admit, but these are unit tests after all (suggested improvements welcome!).
A SQLite memory database only exists as long as the connection to it remains open. To use it in unit tests with NHibernate:
1. Open an ISession at the beginning of your test (maybe in a [SetUp] method).
2. Use the connection from that session in your SchemaExport call.
3. Use that same session in your tests.
4. Close the session at the end of your test (maybe in a [TearDown] method).
Just a wild guess, but is the sql output by NHibernate using a command unsupported by sqlite?
Also, What happens if you use a file instead of memory? (System.IO.Path.GetTempFileName() would work i think...)
We are using SQLite in memory for all our database tests. We are using a single ADO connection for the tests that is reused for all NH sessions opened by the same test.
This allows also running tests with several sessions included. The SessionFactory is also created once for all tests, because the reading of the mapping files takes quite some time.
Edit
Use of the Shared Cache
Since System.Data.Sqlite 1.0.82 (or Sqlite 3.7.13), there is a Shared Cache, which allows several connections to share the same data, also for In-Memory databases. This allows creation of the in-memory-database in one connection, and use it in another. (I didn't try it yet, but in theory, this should work):
file::memory:?cache=shared