force nhibernate to save unchanged object (mark it as dirty) - nhibernate

I need to save a unchanged object via nhibernate to get a database trigger fired.
So how can I tell nhibernate that this object is dirty even if no property has changed?

There are NHibernate extension points, exactly for this scenario. In this case, we can append custom EventListener or introduce an IInterceptor.
Check this question How to make NHibernate considered property to always be dirty when using dynamic update or insert? for a solution (answer based on IInterceptor)
See the NHibernate documenation 12. Interceptors and events

So in respect to my comment to Radims answer I did the following:
I changed one entry of the loadedstate array of the entity so nhibernate will see it as changed on next save.
I know that this is a bit of a workaround but for me it works so far.
EntityEntry entry = sessImpl.PersistenceContext.GetEntry(dbo);
entry.LoadedState[x] = y;

Related

Have NHibernate ignore not set properties?

I have a huge object, it has a lot of lazy loadable properties.
I want to enable a quick edit of a very small subset of its property.
How can I, when I just have a few values, tell NHibernate: don't touch anything else?
Because now, when I save, everything not set gets lost.
Have you tried dynamic-update option on your class mapping?
<class name="SomeEntity" dynamic-update="true">
But check if the flush does not cause the unloaded lazy properties to get loaded first, just in case.
In your question, you state you lose other properties. I have never witnessed such a behavior. Are you attaching (using ISession.Update or ISession.Merge) a detached entity in your current code?
What I am suggesting will not work in such a case. It should instead work with an entity loaded from the current ISession, touched on some properties then saved to db only using ISession.Flush (or preferably, ITransaction.Commit, since it is not a good practice to work without transactions).

Get rid of UoW's implicitness

NHibernate's Session and EF's ObjectContext are implementations of Unit of Work pattern and suggest similar approaches for change tracking: you retrieve some entities, then modify them somehow and after that call SaveChanges/SubmitChanges/Save/etc.
I don't like the implicitness of this approach. I don't like that entity modification automatically means it will be saved. I would like to explicitly mark entities that should be saved. What are the best ways to achieve this kind of control in NHibernate or EF?
(note: fortunately I've never dealt with EF; my answer is about NH only)
I think your initial assumption is wrong:
entity modification automatically
means it will be saved
that's not true; in order to persist the changes you've made you need to either:
call Session.Flush() yourself
set Session's flush mode to AutoCommit (highly not recommended)
use an ITransaction and commit it (by far the best approach).
unless you do any of the above your changes would not be persisted.
Personally I feel that NH gives me complete control over what goes into my DB.
here's a good article.

Is there a way to use the NHibernate session to figure out if changes need to be written to db?

I'm using NHibernate here with C#. I have a cache of nhibernate objects that have lazily loaded objects inside of those that might have changes written to them. I need a way to determine if there are changes that need to be saved. It's quite a lot of effort to set flags when one little thing changes and also quite annoying to compare a cache with a copy of an original (because of the lazy loading).
Just wondering if there's a way I can use the current session object to know if it has pending changes that are about to be written to the db, this is so that I can have a 'do you want to save' prompt if in fact there are changes. I can't autosave, the customer demands a save button.
NHibernate.ISession exposes an IsDirty() method so you should be able to check that.

NHibernate overwrite the concurrency in optimistic scenario

I have implemented optimistic locking for concurrency situations.
I have used the version property in the mapping files to link to a integer.
My aim is that if a user tried to save an out-of-date object, she will be given the option to overwrite changes.
I have easily managed to get the SaveOrUpdate to throw an exception, but how do I now override that so that if the user so wishes, the current object overwrites the existing persisted object, while still updating the version number, and without doing a manual member-wise copy of the variables into the non-stale object?
This seems like this is a regular logical scenario, but I don't see any built-in mechanism for this.So is this an anti-pattern?
Thanks for your help and insight.
Kind regards
LJ
I think you should look into the session.Merge method.
Jide

Ignore public/internal fields for NHibernate proxy

I have some entity types that I would like to lazy load. However, they have some internal (assembly) fields they expose, but are not used outside that class. These fields are compiler generated (F#) and I cannot change them. The an example exception is:
NHibernate.InvalidProxyTypeException:
The following types may not be used as
proxies: Mappings.MTest: field id#47
should not be public nor internal
I understand why NHibernate is doing this, and how having fields, if I accessed them, would mess up the lazy-loading properties of the proxies that are generated. However, since I know I won't be using the fields, can I override NHibernate somehow?
Is there any way I can say "ignore this field"? I'm using Fluent NHibernate, if that makes it easier.
Edit: I should also note, I'm using NHibernate 2.1.0 Alpha 2.
Edit2: The main gist here is that I want to keep LazyLoading enabled, which means I have to use the proxy generation. Disabling LazyLoading works (no proxies), but sorta defeats the purpose of a nice framework like NHibernate.
I reassembled NHibernate (easier than getting the source and rebuilding) and removed the code that errors on internal/public fields. LazyLoading appears to work just fine without that check. (Although, I'm new to NHibernate and so there are probably scenarios I don't know about.)
Edit:
Ah, there is a property, "use_proxy_validator" that will disable all validation checks. Good enough.
Fluently.Configure()
.ExposeConfiguration(fun cfg ->
cfg.Properties.Add("use_proxy_validator", "false"))...
Just set the lazy property to false,
<class name="OrderLine" table="OrderLine" lazy="false" >
you can read more in:
Must Everything Be Virtual With NHibernate? - http://davybrion.com/blog/2009/03/must-everything-be-virtual-with-nhibernate/
Ofir,
www.TikalK.com
You can use the
[XmlIgnore]
attribute to decorate the fields :)
Can you use an Interface to declare the fields "used" ?http://nhibernate.info/doc/nh/en/index.html#persistent-classes-poco-sealed
"Another possibility is for the class to implement an interface that declares all public members"
I don't know if NH use the same #transient annotation/attribute as the JAVA version to ignore a property in persistent operations.
You might want to take a look at this page which gives an overview of using F# with Fluent NHibernate.
Edit I just noticed your username. Am I correct in perhaps thinking that this is your blog? How foolish of me. It does seem to address your problem though, specifically "We start off by disabling LazyLoad because most of the properties are not virtual, and NHibernate will fail to validate the mapping. Instead, we explicitly LazyLoad things, like the Store reference."? Maybe I'm just misunderstanding the problem.