3
NHibernate version: 3.3.2.

I have a NHibernate transaction with several operations. As one of the intermediate steps in the transaction, I try to insert a new entity instance with an auto-increment PK via Session.Save.

In some cases there is an error in the insertion caused by a violated Foreign Key value. I catch the exception in order to make some logging and ignore it, assuming the insert has not been done and going on with the following steps. This is a functional requirement and can not be changed. Validating the values before inserting is not an acceptable solution either, according to performance requirements.

My problem: the non-persisted entity has been added to NH session cache but with an empty Id. So I get this exception later when doing some other NH operations:

NHibernate.AssertionFailure: null id in MyApp.MyPackage.MyClass entry (don't flush the Session after an exception occurs)

My question: how can I pull this annoying "zombie" entity off of the session, so I can successfully commit the transaction at the end of all steps?

I can't Evict it, because the Id is empty.

I tried it and got following exception:

System.InvalidOperationException: cannot generate an EntityKey when id is null

I can't either Clear() the current session as I am in the middle of a transaction and have some previous and following steps to be preserved.

The original exception I got was somewhat confusing, and was thrown at a different point from where the real problem was originated. This link gave me some information to figure out what was happening: NHibernate - null id in entry (don't flush the Session after an exception occurs)

Keren Caelen
  • 1,466
  • 3
  • 17
  • 38
Diana
  • 2,186
  • 1
  • 20
  • 31
  • How do you evict it? Session.Evict(objReference) ? – epitka Jun 20 '13 at 15:52
  • @epitka Yes, and I use the same entity instance I used when calling session.Save. It has property Id value = 0, it should have been filled by Save if it would have been inserted correctly. – Diana Jun 20 '13 at 17:05

2 Answers2

0

As much as it sucks, I've been able to get around this by wrapping my zombie.discard() in a 'try/catch', and when I do so, it suppresses the nastier "null id in your.object entry (don't flush the Session after an exception occurs)"

I feel dirty.

alcoholiday
  • 719
  • 5
  • 10
0

According to NHibernate Manual, 9.8. Exception handling:

If the ISession throws an exception you should immediately rollback the transaction, call ISession.Close() and discard the ISession instance. Certain methods of ISession will not leave the session in a consistent state.

I guess you have to restart the whole transaction in your case.

Leonid
  • 16
  • 3
  • Finally I had to change the logic and sacrifice performance to check the FK violation beforehand to avoid the exception, as I didn't find any other way to restore the session state after the exception. – Diana Mar 26 '14 at 18:14