Tuesday, January 31, 2012

Mapping-by-Code - Join

We have previously explored the one-to-one mapping, which lets us create 1:1 association in the database, but there is actually another way to map several tables to an object model. We aren't constrained by the database model, and we can merge several tables into a single entity. We do that using the <join> element. It can be mapped with mapping-by-code using Join method pretty easily:

Join("table_name", j =>
{
// join options
j.Table("table_name");
j.Schema("schemaName");
j.Catalog("catalogName");

j.Fetch(FetchKind.Join); // or .Select
j.Inverse(true);
j.Optional(true);

j.Key(k =>
{
k.Column("columnName");
// or
k.Column(c =>
{
c.Name("columnName");
// etc...
});

k.ForeignKey("foreignKeyName");
k.NotNullable(true);
k.OnDelete(OnDeleteAction.Cascade); // or .NoAction
k.PropertyRef(x => x.Name);
k.Unique(true);
k.Update(true);
});

j.Loader("customLoader");
j.SqlInsert("custom SQL");
j.SqlUpdate("custom SQL");
j.SqlDelete("custom SQL");
j.Subselect("custom SQL");

// joined element mappings
j.Property(x => x.MayorName);
// etc...
});

The first parameter, named mysteriously splitGroupId, is an identifier serving by default as the joined table name. The second parameter is used both for join options and mapping the joined elements.

The Key method is an equivalent of XML <key> element, that is required in join mapping. In mapping-by-code it is not required, default convention can handle it. But in case we want to customize anything about the foreign key and its database column, we have standard options available there. All the other XML mapping features are available, too - it's pretty easy to figure out as all its names matches XML attributes or elements names.

The only missing thing, as always in case of custom SQL queries, is the possibility to set up checking the value returned by the query - an equivalent for check attribute in custom queries XML elements.

Fluent NHibernate equivalent

Join mapping in Fluent NHibernate is very similiar to mapping-by-code. The first parameter of Join method is the joined table name, the second are for other options and joined element mappings.

Join("table_name", j =>
{
// join options
j.Table("table_name"); // void
j.Schema("schemaName")
.Catalog("catalogName")
.Fetch.Join() // or .Select()
.Inverse()
.Optional()
.KeyColumn("columnName");
j.SqlInsert("custom SQL").Check.RowCount();
j.SqlUpdate("custom SQL").Check.None();
j.SqlDelete("custom SQL");
j.Subselect("custom SQL");

// joined element mappings
j.Map(x => x.Name);
// etc...
});

There are few options missing - the only thing we can define about the foreign key column is its name - using KeyColumn method. The strange thing is that Table method returns void thus it's not chainable.

Monday, January 30, 2012

Mapping-by-Code - OneToOne

Moving on with relation types in NHibernate - we haven't talked about <one-to-one> yet. The name suggests that it's designed for 1:1 relationships and this is not quite correct. 1:1 relationships can be mapped simply using many-to-one with unique constraint. One-to-one is designed specifically for making that many-to-one relationship with unique constraint bidirectional.

This kind of relation is mapped using many-to-one on the side that owns the relationship (in terms of having foreign key column in the database) and one-to-one on the second side. Note that at one-to-one side there's no column at the database level - the relationship from "one" side is "virtual", maintained only by NHibernate.

In mapping-by-code we're mapping it using OneToOne method. It has two parameters. The first one is the lambda pointing to the mapped property, as always. The second one are the options.

OneToOne(x => x.User, m =>
{
m.Cascade(Cascade.Persist);
m.Constrained(true);
m.Lazy(LazyRelation.Proxy); // or .NoProxy, .NoLazy
m.PropertyReference(typeof(User).GetPropertyOrFieldMatchingName("OtherSideProperty"));
m.OptimisticLock(true);
m.Formula("arbitrary SQL expression");
m.Access(Accessor.Field);
});

Two things to note here. The first one is the lack of possibility to choose the fetch mode and foreign key name. The second one is the cumbersome construct needed to map property-ref option - the method is called PropertyReference instead of standard PropertyRef and its parameter is MethodInfo-typed instead of standard lambda expression or string at least. It looks like the feature went to production before it was finished.

Fluent NHibernate's equivalent

Fluent NHibernate's name for one-to-one is HasOne. I think this is the most often misused method in FNH as it looks like a natural sibling for HasMany and HasManyToMany and it seems to be a good choice for many-to-one mapping (which turns out to be mapped by References method). A bit messy, isn't it?

Here's how to use it:

HasOne(x => x.User)
.Cascade.SaveUpdate()
.Constrained()
.LazyLoad(Laziness.Proxy) // or .NoProxy, .False
.PropertyRef(x => x.OtherSideProperty)
.Access.Field()
.Class<CustomType>()
.Fetch.Join() // or .Select(), .Subselect()
.ForeignKey("foreignKeyName");

Apart for the name issue, it's a bit better than in mapping-by-code this time. The only option not available here is formula.

Friday, January 27, 2012

Mapping-by-Code - concurrency

It's time for less exhausting topic - concurrency mapping. There are two different aspects of concurency-related mappings.

The first one is entity-level mapping, where we choose the concurrency model (for optimistic concurrency). In XML, in <class> mapping, there are two attributes regarding the optimistic concurrency - optimistic-lock and dynamic-update. The former is not supported in mapping-by-code. The latter can be set using simple method in ClassMapping:

DynamicUpdate(true);

Another concurrency model is to use explicit versioning with separate column that keeps either timestamp or version number incremented on each update. In XML, this column is mapped using <version> element. There's corresponding method in mapping-by-code:

Version(x => x.Version, m =>
{
m.Column("columnName");
// or
m.Column(c =>
{
c.Name("columnName");
// etc...
});

m.Generated(VersionGeneration.Always); // or VersionGeneration.Never
m.UnsavedValue(0);
m.Insert(true);

m.Type(new TimestampType());
// or
m.Type<CustomType>();

m.Access(Accessor.Field);
});

The mapping is not a surprise. The first parameter is an expression pointing to mapped property, the second is for the configuration. We can specify column properties using standard Column method. We can define whether the value is generated at database side using Generated method. We can choose what value should be assigned to newly created objects using UnsavedValue method. We can also define whether the value should be considered when building insert query using Insert method. We can choose how NHibernate is accessing the value, using Access method. Finally, using the Type method, we can decide on the type used for versioning - most common are numeric and timestamp types.

Fluent NHibernate equivalents

Entity-level mappings for concurrency options in FNH are available through the two methods:

DynamicUpdate();
OptimisticLock.Dirty(); // or .All(), .None(), .Version()

And here is the mapping for version property:

Version(x => x.Name)
.Column("columnName")
.Generated.Always() // or .Never()
.UnsavedValue("0") // string?
.Access.Field()
.CustomType("timestamp")
// or
.CustomType<CustomType>();

Insert seems to be not supported. UnsavedValue is string-typed, what looks a bit strange i.e. if we want to set it to numeric value.


Two next posts in Ayende's series are about NHibernate properties mapped at global level, above entity level - <database-object>, named queries, <query> and <sql-query>. I'll skip these as they do not fit into mapping-by-code ClassMappings series. I'll maybe come back to it separately.

Tuesday, January 24, 2012

Mapping-by-Code - OneToMany and other collection-based relation types

This post is going to be a continuation for the previous one, about Set and Bag mappings. Previously I've described collection and key column mappings. This time I'll cover mapping part that defines the relation type the collection takes part in.

There are five relation types supported by collections. I'll list it with its HBM names:

  • one-to-many - when the collection elements are entities
  • many-to-many - same, but storing the relation in separate table to allow m:n relations
  • many-to-any - heterogenous association with entities of different types
  • element - when the collection elements are single-column value types
  • composite-element - when the collection elements are multiple-column value types (components)

In mapping-by-code, the relation type is defined in the third parameter of Set/Bag mapping. It is optional, with default one-to-many. There's a method for every relation type. Let's go through that methods one by one - I'll show only the lambda from third Set/Bag method parameter.

The first one is OneToMany, for one-to-many entity mapping, obviously.

r => r.OneToMany(m =>
{
m.NotFound(NotFoundMode.Exception); // or NotFoundMode.Ignore
m.Class(typeof(CustomType));
m.EntityName("entityName");
})

It has an optional parameter with configuration. NotFound defines the NHibernate behavior when the referenced entity is missing in the database. Class and EntityName allows to set up the relation for non-standard other side mappings.

Next is ManyToMany. The main difference is how the relation is stored in the database. ManyToMany relation needs an intermediate table with foreign keys to allow m:n relations. There are several options available affecting how the additional table looks like.

r => r.ManyToMany(m =>
{
m.Column("otherKeyColumnName");
// or
m.Column(c =>
{
c.Name("otherKeyColumnName");
// etc...
});

m.ForeignKey("otherKey_fk");
m.Formula("arbitrary SQL expression");
m.Lazy(LazyRelation.Proxy); // or LazyRelation.NoProxy or LazyRelation.None
m.NotFound(NotFoundMode.Exception); // or NotFoundMode.Ignore

m.Class(typeof(CustomType));
m.EntityName("entityName");
})

Configuration parameter of ManyToMany is optional - it may be skipped if we leave all options with default values and set the naming through the convention. In the options there is standard Column method that allows to define name and other DDL-level properties of the key column referencing other side entity (note that we've defined key column for our entity in bag/set mapping options) - it is useful if we don't map the other side and still be able to generate the tables properly. We can also set up laziness through Lazy method, behaviour for not found rows through NotFound or even set up the relation using arbitrary SQL expression instead of foreign key column value using Formula method.

Third one is ManyToAny. This is quite an exotic feature of NHibernate, but there are some cases where it's really useful. See Ayende's post for detailed description. Generally, this is for the case when we have a many-to-many relation with entitles of different types at the other side. NHibernate needs to be said how to distinguish the type of entity and is able to query the proper tables for different objects. Let's stick to Ayende's example:

r.ManyToAny<long>(m =>
{
m.Columns(id =>
{
id.Name("PaymentId");
id.NotNullable(true);
// etc...
}, classRef =>
{
classRef.Name("PaymentType");
classRef.NotNullable(true);
// etc...
});

m.IdType<long>(); // redundant, needs to be specified in ManyToAny parameter
m.MetaType<string>();

m.MetaValue("CreditCard", typeof(CreditCardPayment));
m.MetaValue("Wire", typeof(WirePayment));
})

The generic type in ManyToAny method defines the common type for identifiers of all entities at the other side. Inside the configuration (which is required in this case), we need to define properties for two columns this time - one to keep the other entity identifier, second to keep its discriminating value. We do it using Columns method's parameters. Later we have to specify the type of discriminator using MetaType method and its generic argument - string is good here. We can also specify the common type of identifiers using IdType method, but we've already did it in ManyToAny generic parameter (I think that this method is useless here). The last thing we need to do is to define the list of entity types that are allowed at other side of the relation and its corresponding discriminator values. In order to do this, we call MetaValue method - its first parameter is the discriminator value, second is the type.

The next collection-based relation type available is Element. This is designed for collection of simple value-typed objects, i.e. list of strings.

r => r.Element(m =>
{
m.Column("valueColumnName");
// or
m.Column(c =>
{
c.Name("valueColumnName");
// etc...
});

m.Formula("arbitrary SQL expression");
m.Length(100);
m.NotNullable(true);
m.Precision(10);
m.Scale(10);
m.Type<CustomType>(parameters);
m.Unique(true);
})

The options available are quite standard - there are DDL options for value column available within Column method and different Property-like options describing the value itself. Note that foreign key column options or table options are defined in collection options.

The last possible relation type for collection mapping is Component, known in XML as composite-element. Mapping-by-Code merged these two terms into component, because there is no real difference besides the fact that components were parts of single objects and composite elements were used in collections only.

r => r.Component(m =>
{
m.Property(x => x.Name);
// etc...
})

The mapping itself is like already described component mapping, so I'll skip it here.

Fluent NHibernate's equivalents

As I've already described in the previous post, Fluent NHibernate is not separating the collection mapping from the relation mapping, mixing it together in one method chain. Many-to-any relation is not supported by FNH, and the remaining four types of relations are mapped differently.

Let's go through the mappings - I'll skip the options regarding collection mapping and reflect only these options, that are part of relation mappings in mapping-by-code to keep the comparison consistent.

The first one is HasMany for one-to-many relation:

HasMany(x => x.Users)
.NotFound.Ignore() // or .Exception()
.EntityName("entityName");

HasManyToMany is for many-to-many:

HasManyToMany(x => x.Users)
.ChildKeyColumn("otherKeyColumnName")
.ForeignKeyConstraintNames("parentForeignKeyName", "childForeignKeyName")
.NotFound.Ignore() // or .Exception()
.EntityName("entityName");

Formula mapping is missing. Foreign key name configuration is joined for both sides. There are few more options regarding "child" (other entity) key column, all with names starting with Child.

Many-to-any relation is not supported in Fluent NHibernate.

The next one is element relation, merged into HasMany method, available in the chain through Element method:

HasMany(x => x.Users)
.Element("valueColumnName", m =>
{
m.Formula("arbitrary SQL expression")
.Length(100)
.Type<CustomType>();
})

Other element relation options are not supported.

And finally, there is composite element (component) mapping, named Component here, too. It is also merged into HasMany chain.

HasMany(x => x.Users)
.Component(m =>
{
m.References(x => x.Name);
// etc...
})

Saturday, January 21, 2012

Mapping-by-Code - Set and Bag

It's time for a huge topic - collections. The original Ayende's post was about <set> in the context of one-to-many relationship. I'm going to change it a bit and start with showing how to map sets and bags using mapping-by-code vs. Fluent NHibernate, ignoring the relation context (i.e. one-to-many or many-to-many) - it is clearly separated both in XML mapping and in mapping-by-code. I'll describe different relation types mappings handled by sets and bags in the separate post.

Contrary to Fluent NHibernate and likewise XML mapping, the collection type is a starting point for the mapping. The options are exactly the same in <set> and <bag>, they differ only with the method name - Set vs. Bag. I'll show Set here, for Bag just change the method called in the first line.

Set(x => x.Users, c =>
{
c.Fetch(CollectionFetchMode.Join); // or CollectionFetchMode.Select, CollectionFetchMode.Subselect
c.BatchSize(100);
c.Lazy(CollectionLazy.Lazy); // or CollectionLazy.NoLazy, CollectionLazy.Extra

c.Table("tableName");
c.Schema("schemaName");
c.Catalog("catalogName");

c.Cascade(Cascade.All);
c.Inverse(true);

c.Where("SQL command");
c.Filter("filterName", f => f.Condition("condition"));
c.OrderBy(x => x.Name); // or SQL expression

c.Access(Accessor.Field);
c.Sort<CustomComparer>();
c.Type<CustomType>();
c.Persister<CustomPersister>();
c.OptimisticLock(true);
c.Mutable(true);

c.Key(k =>
{
k.Column("columnName");
// or...
k.Column(x =>
{
x.Name("columnName");
// etc.
});

k.ForeignKey("collection_fk");
k.NotNullable(true);
k.OnDelete(OnDeleteAction.NoAction); // or OnDeleteAction.Cascade
k.PropertyRef(x => x.Name);
k.Unique(true);
k.Update(true);
});

c.Cache(x =>
{
x.Include(CacheInclude.All); // or CacheInclude.NonLazy
x.Usage(CacheUsage.ReadOnly); // or CacheUsage.NonstrictReadWrite,
// CacheUsage.ReadWrite, CacheUsage.Transactional
x.Region("regionName");
});

c.SqlDelete("SQL command");
c.SqlDeleteAll("SQL command");
c.SqlInsert("SQL command");
c.SqlUpdate("SQL command");
c.Subselect("SQL command");
c.Loader("loaderRef");
}, r =>
{
// one of the relation mappings (to be described separately)
r.Element(e => { });
r.Component(c => { });
r.OneToMany(o => { });
r.ManyToMany(m => { });
r.ManyToAny<IAnyType>(m => { });
});

Whoa! The first parameter, not surprisingly, is the lambda expression for the collection property we're mapping. Second one allows to configure the set/bag using a bunch of options. Third one, optional, defines the type of relation the collection takes part in - one-to-many by default (I'll write about relation types separately).

Let's see what options set and bag have to offer and how it differs from XML mappings.

Fetch, BatchSize and Lazy define how and when the collection is loaded from the database. Table, Schema and Catalog say where to look for the collection data in the database. Inverse is useful for bidirectional relationships and defines which side is responsible for writing.

Cascade tells how operations on the entity affects the collection elements. Note that in mapping-by-code it is redefined a bit. Here are the possible values and its corresponding XML values (note that All still doesn't mean literally all values; DeleteOrphans still needs to be specified aside).

[Flags]
public enum Cascade
{
None = 0, // none
Persist = 2, // save-update, persist
Refresh = 4, // refresh
Merge = 8, // merge
Remove = 16, // delete
Detach = 32, // evict
ReAttach = 64, // lock
DeleteOrphans = 128, // delete-orphans
All = 256, // all
}

Combining the values can be done using logical | operator or using syntax provided through extension methods:

Cascade.All.Include(Cascade.DeleteOrphans);

Coming back to bag/set options. Where, Filter and OrderBy affect what data are loaded from the database. Where and OrderBy allows to specify any SQL expression for narrowing and sorting the collection at database level. Furthermore, OrderBy has an overload that makes it possible to specify the ordering by an expression, too. Filter is even more powerful - see another Ayende's post for an explanation.

All the options above, up to Key call in my example, have corresponding XML attributes in <bag> or <set> XML element. Key and all further options are defined in XML as separate elements inside <bag> or <set>.

Key is to define key column in the table that holds collection elements - there are some DDL parameters and behaviors configurable. Key method is a direct equivalent of mandatory <key> element in XML.

Cache controls the second level cache behaviors for the collection. It's an equivalent of <cache> element in XML.

All the SqlXYZ methods are to set up custom ways of reading and writing collection to the database and all of it have its corresponding XML elements, too - useful if we have to use stored procedures for data access. In XML mappings, there's also an ability to tell NHibernate to check what was returned from the procedure, but it seems not supported by mapping-by-code.

The only attribute of Set and Bag that is not configurable in mapping-by-code is generic. It is to determine whether the collection type used is generic. But by default, NHibernate checks this on its own by reflection and I can't see why anyone would need to override this behavior.

Fluent NHibernate's equivalent

Fluent NHibernate redesigned the approach established by XML mappings and made a relation type an entry point (and only required part) of the mapping. Moreover, only relations with entities at the other side are considered "first-class citizens" by FNH. So there are only two entry methods: HasMany and HasManyToMany. Element and component (composite element) mappings are hidden inside HasMany as its options. Many-to-any seems to be not supported.

As I'm not describing relationship types in this post, I'll pick many-to-one as an example just to have an entry point and I'll skip the options connected with relationship itself, focusing on collection and key column options. This way it'll cover about the same options as in mapping-by-code example.

HasMany(x => x.Users)
.AsSet<CustomComparer>() // or .AsSet(), .AsBag()
.Fetch.Join()
.BatchSize(100)
.LazyLoad() // or .ExtraLazyLoad()
.Table("tableName")
.Schema("schemaName")
.Cascade.AllDeleteOrphan() // or .None(), .SaveUpdate(), .All(), DeleteOrphan()
.Inverse()
.Where("SQL command") // or an boolean lambda expression
.ApplyFilter("filterName", "condition")
.OrderBy("SQL expression")
.Access.Field()
.CollectionType<CustomType>()
.Persister<CustomPersister>()
.OptimisticLock.Version() // buggy
.ReadOnly()
.Generic()
.KeyColumn("columnName")
.ForeignKeyConstraintName("collection_fk")
.Not.KeyNullable()
.ForeignKeyCascadeOnDelete()
.PropertyRef("propertyRef")
.KeyUpdate()
.Subselect("SQL command")
.Cache.IncludeAll() // or .IncludeNonLazy, .CustomInclude("customInclude")
.ReadOnly() // or .NonStrictReadWrite(), .ReadWrite(), .Transactional(), .CustomUsage("customUsage")
.Region("regionName");

List of possible options is quite long, too. Let's go through and note the major differences.

AsSet method needs to be called to change the default collection type (bag) to set. I've already mentioned that I don't like the fact that such a fundamental thing like collection type is just an ordinary, optional switch in FNH. Moreover, the overloads with comparer (being equivalent of Sort from mapping-by-code) make AsSet method look like the comparer is the only sense of its existence. And that's obviously not the case.

Several options have names changed in FNH:

  • Filter and its Condition are merged into ApplyFilter,
  • Type is CollectionType this time (instead of FNH's standard CustomType),
  • Column is KeyColumn,
  • ForeignKey is ForeignKeyConstraintName,
  • NotNullable is Not.KeyNullable,
  • OnDelete(OnDeleteAction.Cascade) is mapped by ForeignKeyCascadeOnDelete,
  • Update is KeyUpdate,
  • and finally, quite confusing, Mutable is ReadOnly in FNH. It wouldn't be so surprising if FNH didn't use ReadOnly as a shortcut for Not.Update and Not.Insert in other mappings. And Mutable is something different.

There are several options not supported in FNH, i.e. Catalog, Unique, Loader and custom SQL queries (the latter is surprising, as custom SQL queries are available in component mapping, where it shouldn't). In Cascade, there are only a few options - the less used ones like refresh are not supported.

OptimisticLock is buggy. It allows to define concurrency strategies that are valid at entity level only. For collections, OptimisticLock is just a boolean flag. Running the example above (with invalid .Version() call) results in XML validation error.

There's also a problem with an interface being too fluent, again. When defining cache options, we can in fact define all its values together, what makes no sense.

m.Cache.IncludeAll().IncludeNonLazy().CustomInclude("customInclude")
.ReadOnly().NonStrictReadWrite().ReadWrite().Transactional().CustomUsage("customUsage");

Moreover, when we step into cache configuration, we have no way to go back to collection-level options - so Cache configuration needs to be at the end.

An interesting option available only in Fluent NHibernate is specifying Where condition using an expression. It seems to work only if property names are equal to column names, but anyway, it's much better than plain SQL expression in a magic string (for more complicated cases, this fallback is available, too).

What is surprising, PropertyRef is opposite - it needs to be specified by string in FNH, when mapping-by-code supports strongly-typed expression there.

Wednesday, January 18, 2012

Mapping-by-Code - dynamic component

Dynamic component is a feature that allows to map non-generic key-value collection as a part of our entity, like ordinary properties.

Dynamic component was the hardest feature to map using mapping-by-code up to date. I was cursing at the lack of documentation or examples and struggling with NHibernate's source code for few hours and I was ready to show a white flag this time or assume that this feature is broken in mapping-by-code. Finally I've figured it out - it does work and it's quite neat, actually.

There's no separate method for defining dynamic components in mapping-by-code - overloads of the Component method are used. Here is the overload to be used with accessible IDictionary-typed property:

public void Component<TComponent>(
Expression<Func<TEntity, IDictionary>> property,
TComponent dynamicComponentTemplate,
Action<IDynamicComponentMapper<TComponent>> mapping)
where TComponent : class
{
this.RegisterDynamicComponentMapping<TComponent>(property, mapping);
}

I've pasted the whole code of this method to share my initial confusion. Second parameter, dynamicComponentTemplate, is not used at all and it didn't make a hint what TComponent should be. But it turned out to be very useful. Instead of specifying name and type for each key-value pair, we use this parameter to pass an anonymous class instance being a template. Each key from IDictionary should be defined as a property in the template and any value that allows to determine the proper type should be passed.

The third parameter are the mapping options. Thanks to the template and its anonymous but concrete type, we are now defining the properties mapping as if these are ordinary entity properties. Quite neat, isn't it?

My mapped entity has an IDictionary-typed property. I'm going to persist values for "Founded" and "Municipality" string-typed keys.

entity.Properties["Founded"] = 1497;
entity.Properties["Municipality"] = session.Load<Municipality>(1);

Here's how to map it:

Component(x => x.Properties, new
{
Founded = 0,
Municipality = default(Municipality)
}, dc =>
{
// dynamic component members mappings
dc.Property(x => x.Founded);
dc.ManyToOne(x => x.Municipality);
// etc.

// dynamic component options
dc.Access(Accessor.Property);
dc.Insert(true);
dc.Update(true);
dc.OptimisticLock(true);
dc.Unique(true);
});

My IDictionary-typed property called Properties is specified in the first parameter. "Founded" and "Municipality" keys are defined as properties in the template class (second parameter). Corresponding values from the dictionary will be persisted correctly, thanks to the members mappings defined in the third parameter. Properties dictionary can contain anything - collections, other components etc. - all the entity-level mappings are available here, too.

There are also a few options that define behaviors for the component as a whole, like Access or OptimisticLock. These can be redefined at members mappings options, as usual.

Fluent NHibernate's equivalent

Mapping dynamic components in FNH is easier to figure out, but not so clever - key strings and types needs to be defined explicitly.

DynamicComponent(x => x.Properties, dc =>
{
// dynamic component members mappings
dc.Map<int>("Founded");
dc.References<Municipality>(x => x["Municipality"]);

// dynamic component options
dc.Access.Property()
.Insert()
.Update()
.OptimisticLock()
.Unique()
.ParentReference(x => x["Parent"])
.ReadOnly();

dc.SqlDelete("SQL command");
dc.SqlDeleteAll("SQL command");
dc.SqlInsert("SQL command");
dc.SqlUpdate("SQL command");
});

ReadOnly is just a FNH's shortcut for setting both .Not.Insert() and .Not.Update().

This FNH mapping suffers for the same bug as in case of FNH's Component mapping. It is not possible to map ParentReference or SQL queries for dynamic component and FNH should not expose these options as they have no way to work correctly. In fact, SQL queries are ignored and defining ParentReference causes XML validation error.

Monday, January 16, 2012

Mapping-by-Code - inheritance

Next article in Ayende's NHibernate mapping series is about inheritance mappings. As we know, there are few different approaches to inheritance in database. Let's see how we can map it using NHibernate's 3.2 mapping-by-code.

Let's use the same model as Ayende did:

Single table

And let's begin with single table approach (table per hierarchy):

public class PartyMap : ClassMapping<Party>
{
public PartyMap()
{
Id(x => x.Id, i => i.Generator(Generators.HighLow));

Discriminator(x =>
{
x.Force(true);
x.Formula("arbitrary SQL expression");
x.Insert(true);
x.Length(12);
x.NotNullable(true);
x.Type(NHibernateUtil.String);

x.Column("discriminator");
// or...
x.Column(c =>
{
c.Name("discriminator");
// c.Length(21);
// c.NotNullable(false);
// etc.
});
});
}

public class CompanyMap : SubclassMapping<Company>
{
public CompanyMap()
{
DiscriminatorValue("Company");
Property(x => x.CompanyName);
}
}

public class PersonMap : SubclassMapping<Person>
{
public PersonMap()
{
DiscriminatorValue("Person");
Property(x => x.FirstName);
}
}
}

Single table inheritance mapping consists of two parts - discriminator mapping and subclasses mappings.

Discriminator column is mapped with Discriminator method. Mapping options offered by this method looks a bit messy. Length and NotNullable methods are available both in the Column method options (as in other mappings) and in the discriminator options directly. It looks like they are equivalent, what's called last "wins".

Mapping of subclasses is done through separate mapping classes that inherit from SubclassMapping<T>.

An important thing to remember when mapping inheritance using mapping-by-code is that when registering our mappings we should not look for ClassMapping<T> inheritors only - SubclassMapping<T> (and JoinedSubclassMapping<T> and UnionSubclassMapping<T>, mentioned later) do not inherit from ClassMapping<T>. The solution I'm using is to look for all implementations of IPropertyContainerMapper<T>.

Fluent NHibernate's equivalent for single table

Single table inheritance mapping is almost identical in Fluent NHibernate to mapping-by-code:

public class PartyMap : ClassMap<Party>
{
public PartyMap()
{
Id(x => x.Id).GeneratedBy.HiLo(maxLo: "100");

DiscriminateSubClassesOnColumn("discriminator")
.AlwaysSelectWithValue()
.Formula("arbitrary SQL expression")
.ReadOnly()
.Length(12)
.Not.Nullable()
.CustomType<string>();
}

public class CompanyMap : SubclassMap<Company>
{
public CompanyMap()
{
DiscriminatorValue("Company");
Map(x => x.CompanyName);
}
}

public class PersonMap : SubclassMap<Person>
{
public PersonMap()
{
DiscriminatorValue("Person");
Map(x => x.FirstName);
}
}
}

The way of defining subclasses is identical. The discriminator mapping differs in few names: Force is AlwaysSelectWithValue in FNH, Type is CustomType and Insert(false) can be mapped using ReadOnly. Moreover, the DiscriminateSubClassesOnColumn method, that is an entry point for discriminator mapping, requires specifying discriminator column name explicity - no default provided.

There are some more standard column-related methods available, analogously to mapping-by-code Column method options.

Table per class

The second strategy for mapping inheritance is table per class with joined subclasses. In this option subclasses are stored in separate tables that have foreign key to base class table and are joined with the table for base class, if needed. In this case, in mapping-by-code, we have to map subclasses by inheriting from JoinedSubclassMapping<T>. Here is the example of joined subclass mapping with all available options:

public class CompanyMap : JoinedSubclassMapping<Company>
{
public CompanyMap()
{
Key(k =>
{
k.Column("PartyId");
// or...
k.Column(c =>
{
c.Name("PartyId");
// etc.
});

k.ForeignKey("party_fk");
k.NotNullable(true);
k.OnDelete(OnDeleteAction.Cascade); // or OnDeleteAction.NoAction
k.PropertyRef(x => x.CompanyName);
k.Unique(true);
k.Update(true);
});

Property(x => x.CompanyName);
}
}

Fluent NHibernate's equivalent for table per class

In Fluent, subclasses are mapped by inheriting from the same SubclassMap<T> as in single table strategy. Only the method used differs - instead of DiscriminatorValue, we're using KeyColumn method with column name in the parameter (required, no default value). Looks like there's no way to configure other key column's options here.

public class CompanyMap : SubclassMap<Company>
{
public CompanyMap()
{
KeyColumn("PartyId");
Map(x => x.CompanyName);
}
}

Table per subclass

The third option is to use table per subclass with unioned subclasses. This time there is no separate table for base class, common columns are specified in each table for subclass separately and subclass tables share the same key generator. Mapping union subclasses with mapping-by-code is fairly simple - we just need to map the class by inheriting from UnionSubclassMapping<T> - no additional requirements or options.

public class CompanyMap : UnionSubclassMapping<Company>
{
public CompanyMap()
{
Property(x => x.CompanyName);
}
}

Fluent NHibernate's equivalent for table per subclass

Again, in Fluent, subclass maps inherit from the same SubclassMap<T>. To differentiate this strategy from the single table strategy, we have to include a call to UseUnionSubclassForInheritanceMapping method in the parent class mapping.

public class PartyMap : ClassMap<Party>
{
public PartyMap()
{
Id(x => x.Id).GeneratedBy.HiLo(maxLo: "100");
UseUnionSubclassForInheritanceMapping();
}

public class CompanyMap : SubclassMap<Company>
{
public CompanyMap()
{
Map(x => x.CompanyName);
}
}

public class PersonMap : SubclassMap<Person>
{
public PersonMap()
{
Map(x => x.FirstName);
}
}
}

Saturday, January 14, 2012

NullReferenceException in StructureMap after refactoring

I've encountered strange NullReferenceException in StructureMap when defining constructor arguments for the dependency after major refactoring and making previously abstract class non-abstract. Here is the code I had:

public interface IClass {}

public /*abstract*/ class Class : IClass
{
protected Class(string test) {}
}

public class TheRegistry : Registry
{
public TheRegistry()
{
For<IClass>().Use<Class>()
.Ctor<string>().Is("test");
}
}

And here's the stack trace of inner NullReferenceException:

   at StructureMap.Graph.Constructor.FindFirstConstructorArgumentOfType(Type type)
in c:\code\structuremap\Source\StructureMap\Graph\Constructor.cs:line 82
at StructureMap.Graph.Plugin.FindArgumentNameForType(Type type, CannotFindProperty cannotFind)
in c:\code\structuremap\Source\StructureMap\Graph\Plugin.cs:line 92
at StructureMap.Graph.Plugin.FindArgumentNameForType[T]()
in c:\code\structuremap\Source\StructureMap\Graph\Plugin.cs:line 77
at StructureMap.Pipeline.SmartInstance`1.getArgumentNameForType[CTORTYPE]()
in c:\code\structuremap\Source\StructureMap\Pipeline\SmartInstance.cs:line 226
at StructureMap.Pipeline.SmartInstance`1.Ctor[CTORTYPE]()
in c:\code\structuremap\Source\StructureMap\Pipeline\SmartInstance.cs:line 219
at NHManyToMany.TheRegistry..ctor()
in C:\Documents and Settings\Adam\Moje dokumenty\Projects\test\NHManyToMany\TheRegistry.cs:line 21

StructureMap can't find string-typed argument in the constructor. Most probably the exception like this will be thrown where there's no constructor with string argument. But in my case, there was one.

It took me some time to figure out what's wrong here - my constructor is protected, thus inaccessible for StructureMap. I forgot to change it into public after removing the abstract keyword. StructureMap obviously need to have an accessible constructor to work with, so the same issue may come out with internal constructors from other assemblies.

Friday, January 13, 2012

Mapping-by-Code - ManyToOne

Next up for inspection for mapping-by-code is the <many-to-one> element. It's mapping-by-code equivalent is ManyToOne. Here are its possible options:

ManyToOne(x => x.PropertyName, m =>
{
m.Column("column_name");
// or...
m.Column(c =>
{
c.Name("column_name");
// other standard column options
});

m.Class(typeof(ClassName));
m.Cascade(Cascade.All | Cascade.None | Cascade.Persist | Cascade.Remove);
m.Fetch(FetchKind.Join); // or FetchKind.Select
m.Update(true);
m.Insert(true);
m.Access(Accessor.Field);
m.Unique(true);
m.OptimisticLock(true);

m.Lazy(LazyRelation.Proxy);

//m.PropertyRef ???
//m.NotFound ???

m.ForeignKey("column_fk");
m.Formula("arbitrary SQL expression");
m.Index("column_idx");
m.NotNullable(true);
m.UniqueKey("column_uniq");
});

The first parameter (as almost always) is an lambda expression specifying mapped property in our entity. The second (as almost always) are the mapping options.

Column method (as almost always, again) is to specify database column that keeps the relation value. By default, its name is equal to property name, without any "_id" postfix or something. We can change its name only using the overload with string or we can customize all the options using the second overload. Its possibilities are shown in the post about property mapping - it generally works the same way, so I'll skip it here.

Cascade is used pretty often. Note that mapping-by-code redefined it a bit: save-update option is called Persist and delete is Remove here. This is configured using an flags-type enumerable, so it's easy to combine values. There's also an alternative syntax provided using extension methods:

    m.Cascade(Cascade.Persist.Include(Cascade.Remove));

By now, there's no way to map two features useful for legacy inconsistent databases - property-ref and not-found. Maybe Fabio decided that legacy databases wouldn't be mapped with new mappings?

Fluent NHibernate's equivalent

ManyToOne's equivalent in FNH is References:

References(x => x.PropertyName, "column_name")
.Class<ClassName>()
.Cascade.SaveUpdate()
.Fetch.Join()
.Update()
.Insert()
.ReadOnly()
.Access.Field()
.Unique()
.OptimisticLock()
.LazyLoad(Laziness.Proxy)
.PropertyRef(x => x.PropertyRef)
.NotFound.Ignore()
.ForeignKey("column_fk")
.Formula("arbitrary SQL expression")
.Index("column_idx")
.Not.Nullable()
.UniqueKey("column_uniq");

ReadOnly is just a FNH's shortcut for setting both .Not.Insert() and .Not.Update().

Wednesday, January 11, 2012

Mapping-by-Code - Component (and odd cases of Fluent NHibernate's fluency)

Let's move on with mapping-by-code vs. XML vs. Fluent NHibernate. The second post in Ayende's series was about <component> mapping. It's equivalent in mapping-by-code is Component, of course. There are total 6 overloads for Component method - 3 parametrized with lambda expression and 3 with strings for cases where the property is not publicly visible. In each three, there is an overload designed for dynamic components, which are separate topic. So the overloads that interest us have signatures like this:

public void Component<TComponent>(
Expression<Func<TEntity, TComponent>> property,
Action<IComponentMapper<TComponent>> mapping)
where TComponent : class

The first parameter is an lambda expression specifying the property of type TComponent. The second is the component mapping itself - it can contain component's properties mapping (and other class mapping parts except Id) and some options defining component's behavior.

Component(x => x.Address, c =>
{
// mappings for component's parts
c.Property(x => x.City);
c.Property(x => x.ZipCode);
// etc...

// mappings for component's options
c.Parent(x => x.Owner, p => p.Access(Accessor.ReadOnly));
c.Access(Accessor.Property); // or Accessor.Field or Accessor.ReadOnly
c.Class<TownHallAddress>();

c.Insert(true);
c.Update(true);
c.OptimisticLock(true);
c.Lazy(true);
});

Mapping for component's parts can of course contain its own options - i.e. see previous post for Property options.

Parent is a way to create bidirectional relationship between component and its owning entity - it allows mapping back to entity. The only thing that can be customized about this relationship is how should NHibernate access the Parent property in component class - using Access method. This needs to be distinguished from component's Access method, that affects how NHibernate access the opposite - component property in entity. Insert, Update, OptimisticLock and Lazy are about the latter property, too.

One thing is probably missing - both XML and Fluent mapping allows to add Unique constraint on the component, I can't see how to do it with mapping-by-code.

Fluent NHibernate's equivalent

One of the ways to map component in FNH is:

Component(x => x.Address, c =>
{
// mappings for component's parts
c.Map(x => x.City);
c.Map(x => x.ZipCode);
// etc...

// mappings for component's options
c.ParentReference(x => x.Owner)
.Access.ReadOnly()
.Insert()
.Update()
.OptimisticLock()
.LazyLoad()
.ReadOnly()
.Unique();

c.SqlUpdate("update query")
c.SqlInsert("insert query")
c.SqlDelete("delete query")
c.SqlDeleteAll("delete all query")
});

ReadOnly is just a FNH's shortcut for setting both .Not.Insert() and .Not.Update().

Note that Fluent NHibernate allows to specify raw SQL queries for updates, inserts and deletes - mapping-by-code doesn't. But this is not mapping-by-code's limitation, it's rather a FNH bug. Mapping raw queries doesn't make a sense for components, that are by definition owned and managed by its owning entity and NHibernate's XML schema doesn't even allow these attributes in component mapping.

Moreover, FNH's fluency introduces a lot of confusion in cases like this:

c.ParentReference(x => x.Owner).Access.ReadOnly();

It may look like defining an access strategy for parent reference, but no - it is defining an access strategy for the component itself and there's no way to set the former in Fluent NHibernate (at least I can't see any).

Note also that there are three alternative ways to attach component's options and all of it seems to work the same:

Component(x => x.Address, c =>
{
c.LazyLoad().ParentReference(x => x.Owner);
c.ParentReference(x => x.Owner);
})
.ParentReference(x => x.Owner);

And - continuing the exploration of Fluent's API odd cases - setting access strategy and disabling the component from update and insert queries looks like that:

c.Access.ReadOnly().ReadOnly();

Well, now I clearly see the limitations of fluent interfaces. In Fluent NHibernate it can sometimes be more confusing than helpful. Mapping-by-code seems to have much more elegant solution here.

Monday, January 9, 2012

Mapping-by-Code - Property

I am spending quite a lot of time recently with NHibernate 3.2 mapping-by-code feature and as I've already mentioned, my most serious obstacle with this evaluation is that there is virtually no resources on the net. If these answers are everything the Web has to offer, there's a lot of space for improvement.

I am planning to prepare a series of posts covering the most important NHibernate's mapping features implemented using mapping-by-code. I'll probably follow Ayende's great series about XML mappings, at least in terms of ordering. I'm not going to describe the features itself, I'll rather focus on mapping interface. For features description - refer to Ayende's posts.

So let's start with <property>. Its equivalent in mapping-by-code is... Property - isn't it surprising? Well, in Fluent NHibernate it is called Map. There's no rocket science here and everything is pretty simple.

Property(x => x.Property, m =>
{
m.Column("columnName");
// or
m.Column(c =>
{
c.Name("columnName");
c.Default("defaultValue");

c.SqlType("varchar(max)");
c.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1);

c.NotNullable(true);
c.Check("len(columnName) > 1");
c.Precision(2);
c.Scale(2);
c.Index("column_idx");
c.Unique(true);
c.UniqueKey("column_uniq");
});

m.Type<string>(); // or IUserType
m.Update(true);
m.Insert(true);
m.Formula("arbitrary SQL expression");

m.Access(Accessor.Field); // or Accessor.Property or Accessor.NoSetter
// or
m.Access(typeof(CustomAccessor));

m.OptimisticLock(false);
m.Generated(PropertyGeneration.Insert); // or PropertyGeneration.Always or PropertyGeneration.Never

m.Lazy(true);
});

Mapped property goes as lambda expression (or string property name, if it is hidden) in first parameter and this is the only obligatory element - everything else has its defaults and can be skipped (and most often, it should). All the other attributes from the XML have its corresponding method in configuration object in second parameter.

One thing to note is that column can be configured using Column method either with simple string (when customising only name) or with column configuration, that allows to set different DDL-level column properties. Not every feature is implemented in every provider and not every feature makes sense for every column type obviously - i.e. Precision and Scale are for numerics only.

Side note: In the example above I'm specifying SqlType explicitly to varchar(max), but this line

Property(x => x.Name, m => m.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1));

will also produce varchar(max) in SQL Server, and that solution seems to be nicer.

Fluent NHibernate's equivalent

Map(x => x.Property, "columnName")
.Default("defaultValue")
.CustomSqlType("varchar(max)")
.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1)
.Not.Nullable()
.Check("len(columnName) > 1")
.Precision(2)
.Scale(2)
.Index("column_idx")
.Unique()
.UniqueKey("column_uniq")
.CustomType<string>()
.Update()
.Insert()
.Formula("arbitrary SQL expression")
.Access.Field()
// or .Access.Using<CustomAccessor>()
.OptimisticLock()
.Generated.Insert()
.LazyLoad()
.ReadOnly();

The only difference apart from different naming for some properties and Property vs. Map name itself is the ReadOnly method available in FNH. It is just a shortcut for setting both .Not.Insert() and .Not.Update().

Friday, January 6, 2012

Mapping-by-Code naming convention resembling Fluent

Recently I've posted about my first impressions about NHibernate's mapping-by-code and the one thing I was surprised was that the default naming conventions provided are not usable.

I was using default Fluent NHibernate's naming convention for quite a long time and there were only few scenarios (not counting legacy databases) when I needed to specify columns or table names on my own. With mapping-by-code it is not possible to map simple many-to-many without changing the default naming convention or specifying the names in the mapping, quite XML-style. A bit annoying.

So, as a part of my experiments with the tool, I've written another naming convention that is aimed to resemble Fluent NHibernate's default naming convention, so that:

  • foreign key columns in child-parent relationships are called "Parent_id"
  • many-to-many intermediate table is called "FirstToSecond" and its foreign key columns are "First_id" and "Second_id"
  • on bidirectional relations, both sides match together automatically

Nothing really impressing, but missing in default mapping-by-code naming convention.

The code is here on GitHub. Feel free to use it if you find it useful. It is of course far from being complete - it's not even trying to cope with features like maps, one-to-one's, any's, many-to-any's etc.

My convention doesn't support join either and it seems that it is not possible with current mapping-by-code implementation - there's no event to attach to in case of join mapping and it looks like joins are implemented in different way. Foreign key column of joined table is called "parent_key", and can be overriden in ClassMapping only.

I'm inheriting ConventionModelMapper behaviors and adding few own rules, that are applied before mapping, so that it can be overriden in ClassMappings in a standard way. I've used few extension methods provided by NHibernate's code. It's a pity that they are not mentioned anywhere - I've just found it in the source code quite accidentally.

When using my ModelMapperWithNamingConventions in place of ModelMapper or ConventionModelMapper, many-to-many verbose mapping I've presented previously is reduced to something more friendly and quite elegant, like Fluent NHibernate has accustomed me - I can remove key column definitions from both Bag and ManyToMany mapping and remove Table name definition from Bag mapping.

public class Street
{
public Street()
{
Districts = new List<District>();
}

public virtual int Id { get; protected set; }
public virtual string Name { get; set; }
public virtual ICollection<District> Districts { get; set; }
}

public class StreetMap : ClassMapping<Street>
{
public StreetMap()
{
Id(x => x.Id, m => m.Generator(Generators.Identity));
Property(x => x.Name, m => m.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1));

Bag(x => x.Districts, c =>
{
c.Key(k => k.NotNullable(true));
c.Cascade(Cascade.All);
c.Inverse(true);
}, r => r.ManyToMany());
}
}

And here are the tables generated by Hbm2dll tool:

Wednesday, January 4, 2012

NHibernate's Mapping by Code - first impressions

Recently I've found some time to check out NHibernate's 3.2 new mapping-by-code feature that allows to completely remove XML mappings from NHibernate's pipeline.

I'm pretty used to using Fluent NHibernate, but I always think of it as the only alternative to plain hbm.xml mappings, that are just too clumsy and too verbose. I like FNH's fluency and clarity, but I think it's far from being ideal solution. My two major objections are that it hides some very important mapping parts like collection types in defaults and it introduces confusion by renaming some NHibernate's concepts without clear reason (i.e. <property> renamed in FNH to Map(), being totally different from original NHibernate's <map>).

I like the idea of integrated code-first mapping solution in NHibernate to replace FNH pretty much for several reasons:

  • there will be no additional library on which our projects depends;
  • there will be no mismatch between assemblies versions and no additional obstacle for upgrading NH; see often discussed workarounds for the lack of Fluent NH package compatible with NH 3.2 on NuGet (there is already the compatible package, but it's not marked as the latest one, surprisingly);
  • the set of features offered by integrated mapping solution will match NHibernate's core features more likely, along with naming conceptions;
  • last but not least, we'll save on XML transformations that is still done by Fluent NHibernate, as native mapping-by-code skips this step completely.

I've took the conformist, class-by-class approach as I feel it's better for complicated models. I was using Fluent NHibernate's automapping, but it often turned out that almost all entities needed some overrides and this reduces the sense for automapping at all. Moreover, I like being explicit about such an important things like database interactions. Each mapping change should trigger careful testing as mappings are quite fragile part of the application. When mapping changes implicitly together with class structure changes because of some kind of automapping or detailed conventions, the impact of such change can be easily overlooked.

The simple mappings are... simple. For anyone using either XML mappings or Fluent NHibernate, there should be no problem to write class maps. One-to-many relationship looks like this:

public class City
{
public virtual int Id { get; protected set; }
public virtual long Population { get; set; }
public virtual string Name { get; set; }
public virtual Municipality Municipality { get; set; }
}

public class CityMap : ClassMapping<City>
{
public CityMap()
{
Id(x => x.Id, m => m.Generator(Generators.Identity));
Property(x => x.Population);
Property(x => x.Name, m => m.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1));
ManyToOne(x => x.Municipality, m =>
{
m.Cascade(Cascade.All);
m.NotNullable(true);
});
}
}

I've encountered first problems when tried to map many-to-many. It seems like mapping-by-code doesn't come with any useful default naming convention for tables and columns and we need to specify it explicitly in mapping - it looks more like XML in this case. Fluent NH can figure out pretty decent names on its own. I'll probably need to define some conventions to make it resemble Fluent mapping more. Here is what I had to do to make it work (I'm showing one side of the relationship only, but you can see the thing):

public class Street
{
public Street()
{
Districts = new List<District>();
}

public virtual int Id { get; protected set; }
public virtual string Name { get; set; }
public virtual ICollection<District> Districts { get; set; }
}

public class StreetMap : ClassMapping<Street>
{
public StreetMap()
{
Id(x => x.Id, m => m.Generator(Generators.Identity));
Property(x => x.Name, m => m.Length(SqlClientDriver.MaxSizeForLengthLimitedString + 1));

Bag(x => x.Districts, c =>
{
c.Key(k =>
{
k.Column("StreetId");
k.NotNullable(true);
});
c.Cascade(Cascade.All);
c.Table("Streets2Districts");
c.Inverse(true);
}, r => r.ManyToMany(m => m.Column("DistrictId")));
}
}

Now I'm trying to figure out how to map dynamic components, but it's not as easy as it should be. Here is the API I'm trying to use:

public void Component<TComponent>(
Expression<Func<TEntity, IDictionary>> property,
TComponent dynamicComponentTemplate,
Action<IDynamicComponentMapper<TComponent>> mapping)
where TComponent : class

or

protected virtual void RegisterDynamicComponentMapping<TComponent>(
Expression<Func<TEntity, IDictionary>> property,
Action<IDynamicComponentMapper<TComponent>> mapping)
where TComponent : class

Anyway, I don't know what TComponent in case of dynamic components should be. Resources on the web are extremely poor - the only answer I've found was not really helpful.

And here is the main weakness of mapping-by-code for me by now - it's too fresh. There is virtually no documentation apart from a few examples mentioned at StackOverflow. And even the code from initial Fabio Maulo's blog posts introducing the feature are outdated as some things changed before it goes to the production.

It's hard to think about migrating from FNH to mapping-by-code if it is still such an unknown land. Anyway, I think the direction is very good and the beginning is promising. I'll probably try to explore this land on my own.