When I allow
NHibernate to generate the schema for my object graph I get an issue with foreign key constraints on collections.
I'm I can't be the only person that has come across this problem!? I'll try and outline it for you. Ps. At the end of this post I do have a solution!
I have an abstract base class that has a simple
IList<string>
public abstract class VariationBase : DomainBase
{
public IList<string> OtherVariations { get; set; }
}
Then I have a number of other classes that inherit from
VariationBase (The idea being that each class could have a title variation for example).
When
NHibernate creates the SQL to create the schema it creates a foreign key constraint on the first class that it comes across.
The problem with this is that if I were to insert a new object that was not the class that the constrain is on I will get an foreign key constraint violation.
Solution 1.
After
NHibernate has created the Schema go back into SQL and remove the constraint manually.
This is not great because every time you generate the schema you must remember to remove this constraint, and this could happen a lot during development!
Solution 2.
When I came across this before I put
inverse=true on my mapping for the collection to generate the schema, then after it had been generated put
inverse back to
false.
This still has the same issue as before in the fact you have to "remember" to do this every time you generate the schema. Also if you are using the latest trunk version of
NHibernate then this method won't work as the line that checks
IsInverse before creating the foreign key constraint has been commented out (I'm sure there is a reason!).
Solution 3.
Add another attribute to the collections mapping in
NHibernate so that you can stipulate
constrain=false. By doing so will tell
NHibernate not to create the foreign key constraint on that collections table. This is the preferred method as once the work in
NHibernate is done I no longer have to worry about it.
You can download the patch that adds this functionality
here.
Remember that if you use this patch that you will have to re-generate the Cfg/MappingSchema/Hbm.generated.cs using the HbmXsd tool (NHibernate.Tool.HbmXsd).
I have also included a patch for
ActiveRecord so that you can add this property to your collection attribute e.g. (notice the
Constrain = false Property):
public abstract class VariationBase : DomainBase
{
[HasMany(typeof(string), ColumnKey = "Original", Table = "OtherVariations", Constrain = false, Element = "Variation", Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
public IList<string> OtherVariations { get; set; }
}
I was wondering if anyone else has come across this problem? Or if there is a better solution that is already in place?
I'm thinking about submitting these patches to the relevant people to be committed into the trunks of
NHibernate and
ActiveRecord, but I'm not sure if it is useful enough and would be used?
Let me know what you think I should do...is it worth submitting?