The Problem
Using Hibernate on a (.Net/C#) project and came to delete a record from a “collection” and this threw an error
the given key was not present in the dictionary
After much head scratching it was determined that the problem was down to a subtle interaction between NHibernate and a DataBase C# entity class.The class overrode the GetHashCod() method
public override int GetHashCode() { ... }
Originally the underlying database table has a composite key utilising two integer columns, the GetHashCode() method used both of these columns to generate the (unique) hash code. A database modification moved from a composite key to a single key, however, the GetHashCode() method was not updated.
Everything worked fine for read but Delete threw an exception. So what was going on?
Upon investigation it was found that, as part of NHibernate initialisation or lazy-loading, when reading the data the primary key column was populated but the defunct key column was zero, but the GetHashCode() method was called. Later on in the lifecycle all the properties of the Db class were populated and this meant a different hash code was generated (as the defunct column’s value was populated and the GetHashCode() method used this value as well as the primary key value – see earlier). So it looks like that, initially, items were read by NHibernate and added to it’s internal “collection” with hash-codes from partially loaded data, whereas the delete was being made for an item with a hash-code generated from fully populated data – and NHibernate could not find that item in the collection. It looked like NHibernate was using the hash-code to identify individual items.
The solution
Generate a hash-code (GetHashCode() method) using only the primary key.