As you've already experienced, cascading is not supported on the index
element/mapping. While elements like
do support cascade
, the index-many-to-many
is just another index, which nature is not intended to be cascade supporting.
My suggestion would be: do not use the map. Introduce brand new object instead, represented by table UserAddedFields
. If we'd extend it with a surrogated primary key, we can have an object like:
public class UserAddedFieldSetting
{
public virtual int Id { get; protected set; }
public virtual Product Product { get; set; }
public virtual UserAddedField UserAddedField { get; set; }
public virtual decimal FieldValue { get; set; }
which can be mapped as a <bag>
, i.e: IList<UserAddedFieldSetting>
. Not only it will support cascading on the many-to-one
mapping of the UserAddedField
, but also the querying will be much more simple and straightforward
<bag name="UserAddedFields" lazy="true" inverse="true"
batch-size="25"
cascade="all-delete-orphan">
<key column="parent_id" />
<one-to-many class="UserAddedFieldSetting" />
</bag>
EXTEND:
So, now, we have a mapping (see updated part in the question), which is working as needed - well almost. The issue is, that NHibernate is executing the SaveOrUpdate()
on our many-to-one
relation.
The problem here is, how to decide, that SaveOrUpdate
should INSERT or UPDATE? And NHibernate decided to UPDATE by the way... but the row count returned was 0. Because there was in fact no row to update. We need to insert.
The key to the answer is in the mapping of the "unsaved value", the value representing the new == "to be inserted" state.
So let's extend the mapping:
<class name="UserAddedField" >
<id name="Id" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid" />
</id>
...
And be sure, that every new C# instance of the UserAddedField
has the
Id = Guid.Empty;
Now, NHibernate, when the SaveOrUpdate is called, will know, that Guid.Empty
means do INSERT...