Hi All,
I am using Hibernate 3.1.2 inside Spring to power my Tomcat webapp. I have an object with some arbitrary metadata attached to it; the metadata is stored in a HashMap<String, Serializable>, and is serialized into a BYTEA column (as you can see from the excerpts below).
In my webapp, I display a list of objects on the screen, and provide a "next" button that the user can click to display them one after another. The objects are in a parent-child relationship, as you can see below.
The problem is that Hibernate always tries to update each object, because it always thinks that the "metadata" property is dirty. As far as I can tell, Hibernate uses the following code to check if properties are dirty:
Code:
public final class EqualsHelper {
public static boolean equals(Object x, Object y) {
return x==y || ( x!=null && y!=null && x.equals(y) );
}
private EqualsHelper() {}
}
So, my question is twofold:
1). How come x !=y in this case ? This can only happen if I have two instances of an object with the same primary key, but I'm pretty sure I'm not creating extra instances. Besides, shouldn't Hibernate keep track of identical instances in its session cache ?
2). Assuming that, in the worst-case scenario, #1 is unsolvable, how do I fix this ? One answer might be, "represent your Map in a table in the database instead of serializing it in". I'd like to avoid this solution, though, because I could have literally millions of objects in the database, and if each of them has 5 metadata properties on the average, I will have to join against a metadata table with 5 million rows in it.
Thanks for your help...
Hibernate version: 3.1.2
Mapping documents:
<class name="com.digitalmountain.domain.ReviewableItem" table="reviewable_item">
<id name="id" type="long">
<column name="id" sql-type="bigint" not-null="true"/>
<generator class="assigned"/>
</id>
<discriminator column="subclass" type="string"/>
<version name="version" column="version"/>
<many-to-one name="parent" column="parent_id" class="com.digitalmountain.domain.ReviewableItem"
not-null="false" lazy="proxy" cascade="persist"/>
<property name="metadata" column="metadata_map" type="serializable"/>
...
Name and version of the database you are using: PostgreSQL
Debug level Hibernate log excerpt:
2006-06-01 23:38:00,703 DEBUG [org.hibernate.util.SerializationHelper] - Starting serialization of object [{MimeType=application/x-msexcel, primary_author=Dominik Kacprzak, company=Digital Mountain, creation_date=2/18/2005 06:02:14, last_print_date=2/18/2005 08:13:43, Encoding=0, AttachmentShortName=search_e.xls, links_dirty=no, _PID_HLINKS=Features, scale_crop=no, security=0, source=Microsoft Excel, last_saved_by=Dominik Kacprzak}]
2006-06-01 23:38:00,703 DEBUG [org.hibernate.util.SerializationHelper] - Starting serialization of object [{MimeType=application/x-msexcel, primary_author=Dominik Kacprzak, company=Digital Mountain, creation_date=2/18/2005 06:02:14, last_print_date=2/18/2005 08:13:43, Encoding=0, AttachmentShortName=search_e.xls, links_dirty=no, security=0, scale_crop=no, _PID_HLINKS=Features, source=Microsoft Excel, last_saved_by=Dominik Kacprzak}]
2006-06-01 23:38:00,703 DEBUG [org.hibernate.persister.entity.AbstractEntityPersister] - com.digitalmountain.domain.FileItem.metadata is dirty