Friday, June 01, 2007

PersistentMap NotSerializeableException

If you have a java.util.(Hash)Map object, by itself, which contains a map from String to String, you would think it was a Serializeable Map, and nothing more. And it is, until Hibernate gets involved.

When you persist the map, Hibernate add some extra information to it, so that when you retrieve the persisted object, it is no longer a HashMap at all, but an org.hibernate.collection.PersistentMap, which implements the java.util.Map interface. This class claims to be Serializable, and it usually is.

However, as part of all that extra information, Hibernate adds a reference to the object associated with the map. Since that parent object is a hibernate mapped object, I erroneously assumed it would never persist unmapped fields. But I really did not realize it would store the whole object as part of the map that the object belongs to.

In my case, the Object was also additionally holding a reference to a third object, which in turn contained a reference to the map, not just any map, but the PersistentMap, which also held the Request object, and so on, an infinitely recursive reference.

But the real lesson here is not the infinite recursion, but that by going through hibernate to persist a collection, you end up actually storing a hibernate-specific object that contains a lot more data than the java collection itself, so be careful, what goes in is not what comes out: there are potentially storage and performance issues that may result.