I am using Fluent NHibernate to map a composite key. I need the child entity to receive the newly inserted parent key when the parent is created. This works but NHibernate is doing an insert on the child and thereafter doing an update on one of the composite key IDs on the child.
The entity relationships are as follows:
1) Model (parent) - has many FactorWeights.
2) FactorWeight (child) has one Factor.
3) Factors can have different weightings per model.
Since Models have many Factors and the Factor can have different weightings for different models, the FactorWeight entity is required with the composite key of ModelID and FactorID.
Model:
public virtual int ID { get; set; } public virtual IList<FactorWeight> FactorWeights { get; set; } public virtual string Name { get; set; }
Factor:
public virtual int ID { get; set; } public virtual string Name { get; set; }
FactorWeight:
public virtual Factor Factor { get; set; } public virtual Model Model { get; set; } public virtual decimal Weight { get; set; }
The mappings are as follows:
Model:
public void Override(AutoMapping<Model> mapping) { mapping.Id(x => x.ID); mapping.Map(x => x.Name); mapping.HasMany(x => x.FactorWeights) .KeyColumn("ModelID"); }
FactorWeights
public void Override(AutoMapping<FactorWeight> mapping) { mapping.CompositeId() .KeyReference(factorWeight => factorWeight.Model, "ModelID") .KeyReference(factorWeight => factorWeight.Factor, "FactorID"); mapping.Map(factorWeight => factorWeight.Weight); }
I use the following code to create the FactorWeight within the Model object:
Model.FactorWeights.Add(new FactorWeight {Factor = factor, Weight = weighting, Model = Model });
The following is used to persist the entity (where the model is passed to the method):
public void CreateEntity(object entity) { HibernateConfiguration.Session.Transaction.Begin(); NHibernateConfiguration.Session.Save(entity); NHibernateConfiguration.Session.Transaction.Commit(); }
The Model entity is saved without an error as well as the FactorWeight. The problem is that SQL Profiler shows an update on the FactorWeight.ModelID column immediately after the insert. NHibernate updates the FactorWeight.ModelID with the newly inserted ModelID which was already present in the insert.
SQl Profiler Trace:
exec sp_executesql N'INSERT INTO [FactorWeight] (Weight, ModelID, FactorID) VALUES (@p0, @p1, @p2)',N'@p0 decimal(1,0),@p1 int,@p2 int',@p0=1,@p1=56,@p2=1 exec sp_executesql N'UPDATE [FactorWeight] SET ModelID = @p0 WHERE ModelID = @p1 AND FactorID = @p2',N'@p0 int,@p1 int,@p2 int',@p0=56,@p1=56,@p2=1
I assume this is a problem with the mapping of the composite key.
I am using version 2.1.2.400 of NHibernate and version 1.1.0.685 of FluentNHibernate.
Thank you.