I have an object that is saved using Nhibernate. This object use a composite key and is declared like this :
CompositeId()
.KeyProperty(x => x.CreditorName)
.KeyProperty(x => x.CreditorIBAN)
.KeyReference(x => x.Config, "ProfileName");
Map(x => x.ID, "ID").ReadOnly();
Map(x => x.CreationDate, "CreationDate").Default(null);
Map(x => x.ContractReference, "ContractReference");
Map(x => x.CreditorBIC, "CreditorBIC");
References<C_ContractType>(x => x.ContractType, "ContractType_ID");
References<C_Country>(x => x.CreditorCountry, "CreditorCountry");
Table("Creditor");
Cache.ReadWrite();
We can save on without any problem but when we try to update a field (no matter which one) with Session.SaveOrUpdate(entity);
nothing is done (no update) with no error message.
Did we missed something ? Thanks for your help !
-- EDIT --
I add Session.Flush()
after the update method and it's a little better as I can update any value except the ones that are in the key (CreditorName and CreditorIBAN). Any idea ?
I. PERSISTING, executing sql write command
as discussed in the comments, the first thing we need to make that all happened is to extend the our code with a
ISession.Flush()
9.6. Flush
(some cite)
And as discussed here
How to change default FlushMode to Commit in C#?
We can assign the default flush mode during the session creation
And be sure that it will be called once transaction is committed or call it explicitly
anytime
we need toII. Key/Id change for already persisted, not transient entity
This is by design, by intention IMPOSSIBLE. Because the DB
Key
, the C# runtime entityId
is a data layer pointer to the instance. We should not work with these, we should not try to think about themOur entities should just be managed with references:
This way we assign db Keys, represented as Ids... on a Flush(), without mentioning them.
And that's also why we should not think about ability to change them.
The best we can do - is to not use Composite Key - and use
Surrogate Key
With SQL Server it is very easy to introduce new column with IDENTITY(1,1)... just use
ALTER TABLE TheID INT NOT NULL IDENTITY(1,1)
... and its thereRe-map all your composite parts to properties (
.Map()
or.References()
) and then you can change anything you wantI can understand that this is not desired answer, but I would strongly suggest at least to think about it. Simply,