Francois Taljaard
Francois Taljaard

Reputation: 1477

NHibernate FluentMapping

I have the following fluent mapping class. The Component (property) Type on object location is set to Default of empty string and not nullable. When inserting and I get an exception saying I need to specify Type (not nullable), should it not use the default value specified?

public class LocationMapping : FluentNHibernate.Mapping.ClassMap<Cradle.DomainEntities.Location>
    {
        public LocationMapping()
        {
            Id(x => x.ID);
            Map(x => x.Barcode).CustomSqlType("varchar(30)").Unique().Not.Nullable();
            Map(x => x.Name).CustomSqlType("varchar(30)").Not.Nullable();
            Map(x => x.Site).CustomSqlType("varchar(30)").Not.Nullable().Default("");
            Map(x => x.ERPLocation).CustomSqlType("varchar(15)").Not.Nullable().Default("");
            Component<Cradle.DomainEntities.Status>(x => x.Status, c => { c.Map(x => x.Name, "Status").CustomSqlType("varchar(20)"); });
            Component<Cradle.DomainEntities.Type>(x => x.Type, c => { c.Map(x => x.Name, "Type").CustomSqlType("varchar(20)").Default("").Not.Nullable(); });
            Component<Cradle.DomainEntities.Category>(x => x.Category, c => { c.Map(x => x.Name, "Category").CustomSqlType("varchar(20)"); });
            Map(x => x.isActive).Not.Nullable().Default("1");
            Map(x => x.NonStock).Not.Nullable().Default("0");
        }
    }

Component<Cradle.DomainEntities.Type>(x => x.Type, c => { c.Map(x => x.Name, "Type").CustomSqlType("varchar(20)").Default("").Not.Nullable(); });

Upvotes: 0

Views: 332

Answers (1)

Fr&#233;d&#233;ric
Fr&#233;d&#233;ric

Reputation: 9864

Defining Default in mapping does not change .Net defaults.

When you instantiate your Location class, I guess your Type property is not initialized (no initialization value or constructor not setting it) and thus has its default .Net value for a string: null.

NHibernate will not replace that null by the Default you have declared. How could it guess it was not willingly set to null?

You should initialize your class properties with their default values in your class definition.

A sort of workaround could be used nonetheless. For string properties and other nullable properties, you may use the dynamic-insert option on your class, since it causes NHibernate to not send to DB the properties which are null.

See the doc:

(8) dynamic-insert (optional, defaults to false): Specifies that INSERT SQL should be generated at runtime and contain only the columns whose values are not null.

Of course, it cannot work with properties having a non-nullable type.

So, what is the officially supported purposes of defining defaults in mapping? I only know one: enabling DB schema generation from mappings to generate default constraints for columns.

We may consider the dynamic-insert option should take those defaults into account. But if that were the case (and maybe it is, NHibernate doc is sometimes lagging behind implemented functionalities), that would cause my suggested 'workaround' to fail, since the behavior of dynamic-insert should be then to contain only the columns whose values are equals to their declared default in mappings, or null if they do not have a declared default.

Upvotes: 2

Related Questions