NHibernate Pitfalls: Schema Auto Action
This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.
When using NHibernate’s loquacious configuration, you have the change to tell NHibernate what to do with the mappings if the database schema that you are targeting does not exist or does not match the current mappings, when a session factory is created. Like this:
1: Configuration cfg = new Configuration()
2: .DataBaseIntegration(db =>
4: db.BatchSize = 20;
5: db.ConnectionStringName = connectionStringName;
8: db.HqlToSqlSubstitutions = "true 1, false 0, yes 'Y', no 'N'";
9: db.IsolationLevel = IsolationLevel.ReadCommitted;
10: db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
11: db.LogFormattedSql = true;
12: db.LogSqlInConsole = false;
13: db.OrderInserts = true;
14: db.PrepareCommands = true;
15: db.SchemaAction = SchemaAutoAction.Validate;
This value is the same as the property hbm2ddl.auto, that you can set either programmatically:
1: cfg.SetProperty(NHibernate.Cfg.Environment.Hbm2ddlAuto, (createSchema == true) ? SchemaAutoAction.Update.ToString() : SchemaAutoAction.Validate.ToString());
or through XML configuration:
1: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
3: <property name="hbm2ddl.auto">Update</property>
The value you assign to SchemaAction is very important, because it can cause your database to be dropped and created again, losing all data in it!
The possible values are:
Recreate (drop-create): unconditionally drops and creates all of the tables for all of the mapped entities; when the session factory is disposed, drop them again;
Create (create): unconditionally drops and creates all of the tables for all of the mapped entities;
Update (update): check every table against the mappings, and, if there are changes, use DDL commands to update the tables so that they match the schema;
Validate (validate): check the existing tables against the mappings and throw an exception if there are differences.
So, it should be clear that you would only use Create or Recreate for demonstration purposes, self contained unit tests or fresh installations, not real-life scenarios.
Some additional notes:
If you use Recreate, the tables will only be dropped if the session factory is disposed;
For both Create and Recreate, other existing tables are not dropped, only those that are mapped to entities;
Create, Recreate and Update will not create the database, only its tables, it is up to you to create the database;
Update also creates the tables, if they don’t exist;
The default value is Validate.