0
votes

I have situation where a Message table has a primary key (Id) and a foreign key (Site). Any site can create a message record, but only the site that created the record can update it. The problem is that by default it will be updated based upon Id and not Id and Site. I could change the primary key to be a composite/compound id consisting of the id and 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 this in NHibernate without creating a compound id or using Native SQL:

Update MessageTable set MessageStatus = 2 where Id = ? and Site = ?;
3
As a side note, you do not need session.Update in your code. More on this here tobinharris.com/past/2009/6/11/…autonomatt

3 Answers

0
votes

You can't do it directly in NHibernate but you could alter 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();
    }
}

Assuming Site is a string and a property of Message. Also, you will want to wrap your update in a try..catch and rollback the transaction if an exception occurs.

0
votes

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 Ide suggested, but it will require an additional query against the database to pull the original message.

0
votes

What I understand of your question the rule is a business requirement, so maybe NHibernate is not the place to this rule. You can try to implement a listener on the update event : http://nhibernate.info/blog/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.html

An other solution is to mark the property with update to false to prevent the change of the record's site ? http://nhibernate.info/doc/nh/en/index.html#mapping-generated (see generated property)