Reputation: 23234
NHibernate is preventing me from having a unique index that is made of a foreign key and a column when using a uni-directional association.
//The classes
public class Method
{
public virtual Guid ID { get; private set; }
public virtual List<MethodParameter> Parameters { get; private set; }
public Method()
{
this.Parameters = new List<MethodParameter>();
}
}
public class MethodParameter
{
public virtual Guid ID { get; private set; }
public virtual string Name { get; private set; }
protected MethodParameter() { }
public MethodParameter(Method method, string name)
{
this.Name = name;
method.Parameters.Add(this);
}
}
//The mappings
public class MAP_Method : ClassMap<Method>
{
public MAP_Method()
{
this.Table("[Method]");
this.Id(x => x.ID).Access.BackingField().GeneratedBy.GuidComb();
this.HasMany(x => x.Parameters)
.Access.BackingField()
.KeyColumn("[Method]")
.Not.LazyLoad()
.Cascade.AllDeleteOrphan();
}
}
public class MAP_MethodParameter : ClassMap<MethodParameter>
{
public MAP_MethodParameter()
{
this.Table("[MethodParameter]");
this.Map(x => x.Name).Length(50).Not.Nullable();
}
}
If I create a single Method instance with two MethodParameters (Name: x and Name: y) then there is no problem. However if I create two Method instances in the same transaction with the same MethodParameter names then I get a unique index violation.
This is because I have a unique index on [MethodParameter] ([Method] ASC, [Name] ASC), and with uni-directional associations NHibernate first inserts the child tables with NULL for the [Method] column and then goes back and updates the rows with the correct [Method] values.
Obviously this is a problem when inserting two Method instances which have identical MethodParameter names because I end up with (null, "x") (null, "x") instead of (Method1, "x") (Method2, "x")
I understand that this is the designed behaviour, but it seems that I am being forced to either have bi-directional inverse association or remove the unique index from the DB. Is there a way to get NHibernate to insert the correct [Method] ID's when inserting rather than inserting NULL and then updating?
Upvotes: 1
Views: 541
Reputation: 13344
As your association is uni-directional you have to set following options: inverse="false"
on association (<one-to-many>
), not-null="true"
on key (<key>
). If you do not plan to change owners of parameters, then you have to set update="false"
on key (<key>
).
It will prevent from inserting null to FK column.
Example with FluentNHibernate:
this.HasMany(x => x.Parameters)
.Not.Inverse() // 1
.Not.KeyNullable() // 2
.Not.KeyUpdate() // 3
.Access.BackingField()
.KeyColumn("[Method]")
.Not.LazyLoad()
.Cascade.AllDeleteOrphan();
Please take a look at following answer for better explanation https://stackoverflow.com/a/7601312/259946 and https://stackoverflow.com/a/11576097/259946
Upvotes: 1