views:

218

answers:

1

I have what I think is a rather common use case for NHibernate. I create an entity and try to save it using ISession.Save() followed by a Transaction.Commit(). At this point, I expect violations of things like unique/primary key constraints to come up to me as exceptions. What I'm seeing, however, is just a GenericADOException. This doesn't help me differentiate between genuine DB failures versus things like asking the user to choose another name for the entity to preserve uniqueness.

At the moment, I've implemented the ugly workaround of querying first to ensure that the constraints won't be violated. This is just a race condition waiting to happen and I really don't want users to see "Oops, the DB did something funny! Maybe you should try this again." kind of messages.

Is there an elegant way to fix this?

A: 

NHibernate is not aware of constraints (and would be hard pressed to enforce a unique constraint in the first place), so handling this is largely up to you. I think you're on the right track with a query to check that the value doesn't exist, but as you mentioned this leaves the possibility of another process/thread inserting the value first. The solution to that method is an exclusive lock, but of course you have to consider the implications of that lock. I don't know how NHibernate's locking methods work, but if they don't provide what you need you can always access the connection and use raw SQL.

Stuart Childs