How do I add additional criteria to my update command using NHibernate?
I have a situation where a posts table has a primary key (Id) and a foreign key (site). Any site can create a post record, but only the site that created the post can update it. The problem is that by default it will update based on Id, not Id and Site. I could change the primary key to be a composite / composite identifier consisting of an identifier and a site OR resort to Native SQL; however I was wondering if there is a way to add additional update criteria.
For example, this is what you get by default:
public void MessageUpdate (Message oneMessage)
{
using (ISession session = SessionFactory.OpenSession ())
using (ITransaction trans = session.BeginTransaction ())
{
session.Update (oneMessage);
trans.Commit ();
}
}
So, how do I do it in NHibernate without creating a composite id or using native SQL:
Update MessageTable set MessageStatus = 2 where Id =? and Site =?;
source to share
I guess the short answer to my original question is that you cannot add criteria to an update. You can use native SQL to handle this situation as I originally suggested:
Update MessageTable set MessageStatus = 2 where Id =? and Site = ?;
Or you could approach the problem as Jamie Eid suggested, but would require an additional database query to get the original post.
source to share
What I understand about your question, this rule is a business requirement, so maybe NHibernate is not the place of this rule. You can try to implement a listener in the update event: http://nhibernate.info/blog/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.html
Another solution is to mark the property with update to false to prevent the post site from being changed? http://nhibernate.info/doc/nh/en/index.html#mapping-generated (see generated property)
source to share
You cannot do this directly in NHibernate, but you can change your update method to:
public void MessageUpdate(Message oneMessage, string currentSite)
{
if (oneMessage.Site != currentSite)
{
throw new Exception("meaningful error message");
}
using(ISession session = SessionFactory.OpenSession())
using(ITransaction trans = session.BeginTransaction())
{
session.Update(oneMessage);
trans.Commit();
}
}
The intended site is a string and a Message property. Also, you will want to wrap your update in try..catch and rollback the transaction if an exception is thrown.
source to share