tnine wrote:
I am trying to persist a map, the value could potentially be null. When the value is null, I am not getting any rows persisted in the database. If the value is not null, a record is inserted. Is this the expected behavior? I need the key to signal that an object was visited, but if the value of the map is null, then the traversed object did not have a value when it was visited. Therfore, when I load these objects I need to null to signal a special case. Is there any way around to get the row to insert with the null value short of a usertype?
As far as I've investigated, this by design, though I'm not sure the justification. The
PersistentMap class in Hibernate3 (and the
Map class in Hibernate2) treat null values the same as if the key were never set. In fact, if you load a PersistentMap, then set an existing key's value to null, Hibernate will delete that entry.
There's a
bug in this code such that if a null value happens to make it into the persisted map (such as through another, non-Hibernate-enabled client), and Hibernate loads that Map, and you try to overwrite the entry with a non-null value, you can end up with a unique constraint violation, as Hibernate will incorrectly treat the new value as an insert, rather than an update. I've attached a patches for both Hib2 and Hib3 to fix the issue (trivial change---just use containsKey, rather than a null check). Unfortunately, Gavin doesn't see this as a bug, and is "not inclined to fix it." Again, I'm not sure the justification, as Gavin doesn't explain. But he has turned the bug into a low-priority improvement request, which means it will likely be awhile before it gets looked at again.
Personally, I don't understand why PersistentMap
must treat null values the same as if they weren't even in the Map. As you've clearly pointed out, tnine, there's a clear semantic difference between having a null value and not being in the map. Maybe this is answered in the docs somewhere, but it would seem that PersistentMap is imposing an artificial limitation where one isn't necessary.
Currently, the only way around this, as far as I know, is to create your own version of PersistentMap that is null-friendly. Unfortunately, there's no plugin mechanism that would allow you to replace this at runtime, so you'd have to patch your own version of Hibernate.
Or you could file a bug on this. Maybe with enough people asking for it, Gavin will be "inclined to fix it."