Impossible to use SQLite in memory
Hello all,
I'm using FluentNHibernate under VS2010, and thus developping with the .NET 4 framework.
When I use SQLite with a file, I have no problems at all. But when I switch for an in memory database (for unit tests), I have some weird problems. I recreate the database before each test, and so I use the ExposeConfiguration function and inside call :
new SchemaExport(cfg).Create(true, true);
The database is successfully created (I can see that thanks to the ShowSql function), as well the tables, but whenever I want to add an entity in the database, I have the following error:
System.Data.SQLite.SQLiteException: SQLite error
no such table: Dummy
And again, if I switch from InMemory to UsingFile, all works perfectly well.
Is there something that must be done?
Thanks in advance
Support Staff 2 Posted by James Gregory on 20 May, 2010 01:58 PM
An in memory database is destroyed when the session is closed, are you
closing your session?
3 Posted by Michael on 20 May, 2010 02:09 PM
No, I'm not. Here is the code I use:
And here is the complete callstack I have with xUnit:
System.Data.SQLite.SQLiteException: SQLite error
no such table: Dummy
at System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn, String strSql, SQLiteStatement previous, UInt32 timeoutMS, ref String strRemain)
at System.Data.SQLite.SQLiteCommand.BuildNextCommand()
at System.Data.SQLite.SQLiteCommand.GetStatement(Int32 index)
at System.Data.SQLite.SQLiteDataReader.NextResult()
at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)
at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SQLite.SQLiteCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at NHibernate.Id.IncrementGenerator.GetNext(ISessionImplementor session)
NHibernate.Exceptions.GenericADOException: could not fetch initial value for increment generator[SQL: SQL not available]
at NHibernate.Id.IncrementGenerator.GetNext(ISessionImplementor session)
at NHibernate.Id.IncrementGenerator.Generate(ISessionImplementor session, Object obj)
at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Save(Object obj)
at Emidee.NHibernate.Tests.Helper..ctor() in RepositoryTests.cs: line 56
at Emidee.NHibernate.Tests.RepositoryTests.Count_Returns_CorrectNumberOfEntities() in RepositoryTests.cs: line 104
I hope this helps :)
4 Posted by Andy on 21 May, 2010 02:16 PM
Use this as your connection string (don't bother with the other fluent inmemory parts, just use ConnectionString): Data Source=:memory:;Version=3;New=True;Pooling=True;Max Pool Size=1;
Then, add this call after the connection string:
Raw("connection.release_mode", "on_close")
That tells NHibernate to keep your session open until you explicitly close it. Otherwise it closes it because it knows reopening one will be fast due to connection pooling. But it still closes the connection, thus losing your DB.
We're doing this fine with VS2008 / .Net 3.5.
Andy
5 Posted by Michael on 25 May, 2010 12:25 PM
Thanks for your answer, but unfortunately it doesn't change anything.
Support Staff 6 Posted by Paul Batum on 05 Jun, 2010 10:42 AM
Whenever I've wanted to use an in memory db, I've used an approach along the
same lines as this post:
http://www.tigraine.at/2009/05/29/fluent-nhibernate-gotchas-when-testing-with-an-in-memory-database/
Maybe there's an easier way? I haven't found one yet.