views:

34

answers:

1

I have an entity with a surrogate Id and a composite NaturalId mapped with FluentNHibernate. I make the natural id mutable marking it "Not.ReadOnly()". Something like:

    public class EntityMap: ClassMap<Entity>
    {
        public EntityMap()
        {
            Id(x => x.Id);

            NaturalId().Not.ReadOnly()
                .Reference(x => x.OtherEntity, "OtherEntityId")
                .Property(x => x.IntegerProperty);

            // more fields
        }
   }

The generated xml is like:

 <natural-id mutable="true">
      <property name="IntegerProperty" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <column name="IntegerProperty" />
      </property>
      <many-to-one class="OtherEntity, OtherEntity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="OtherEntity">
        <column name="OtherEntityId" />
      </many-to-one>
    </natural-id>

If I change OtherEntity, the operation works fine and the entity is updated in the database. If I change IntegerPropery, I'm getting and exception: "immutable natural identifier of an instance of Namespace.Entity was altered".

Why is it complaining about the "immutable natural identifier" if it is marked as mutable="true"?

The code is something like:

using (var session = SessionManager.OpenSession())
using (var tran = session.BeginTransaction())
{
   session.Update(entity);

   entity.IntegerProperty = (int)differentValue;

   tran.Commit();
}

Thanks

A: 

Properties are .Not.ReadOnly by default.

It's the natural id which is non-mutable by default.

With XML mappings, you'd have to specify mutable="true". Look for something similar in Fluent (I'm not sure if it's supported)

Diego Mijelshon
Checking the hbm generated by fluent I can see that Not.Readonly() sets the mutable="true" to the natural-id tag, but it still fails. So, it seems the issue is at NHibernate level and instead of the fluent mapping. I updated the question to add more information.
Francesc
I believe your best option is removing the natural-id and leaving both properties directly in the class. It's not that important anyway.
Diego Mijelshon
Thanks Diego. What I did at the end was remove the entity and create a new one. In this particular case, this actually makes sense from the business logic perspective, otherwise I'd do what you say as probably a comment stating that those properties form a natural id would be enough. Thanks again for your help.
Francesc