I have an application that where the attributes/properties per class are variable (think XML doc). I'm implementing it as a Map where key and value are both string.
Code:
public class MyClass
{
private String id;
private Map attributes;
public String getId() {
return id;
}
private void setId(String id) {
this.id = id;
}
public Map getAttributes() {
return attributes;
}
public void setAttributes(Map attributes) {
this.attributes = attributes;
}
}
In some cases I could have around 200 entries in this map. I will never use these keys/values in the hashmap for query purposes. (If I did, then this should obviously be implemented as a table so queries can be done).
So now I have the choice of implementing this either as a Serializable column or a Hibernate Map with an associated table.
1) If I implement it as a serializable column, the mapping looks like:
Code:
<id...>
<property name="attributes" type="serializable"/>
2) If I implement it as a table the mapping looks like:
Code:
<id...>
<map name="attributes" table="MYCLASS_ATTRIBUTES">
<key column="MYCLASS_ID"/>
<index column="MAP_IDX" type="string"/>
<element column="MAP_VALUE" type="string"/>
</map>
So finally my question.
Which is more performant? I'm assuming that (1) will be more perfomant as there is no outer join performed and even though I'm invoking the cost of deserialization, it must be less than the cost of inserting all the elements into the map that Hibernate will have to do. However on serialization the cost may be greater in that if the map has only minor changes, I still invoke the cost of seriazliation for (1) whereas in a table approach (2), Hibernate only issues SQL for the changed elements.
If I use solution (1), I assume that Hibernate checks if the class instance at runtime is actually serializable and will throw an exception if it isn't. Since Map does not extend the Serializable interface, it is possible that setAttribute could be handed a non-Serializable instance. So I could protect myself by modifying the setAttributes as follows:
Code:
public void setAttributes(Map attributes) {
if (!(attributes instanceof Serializable))
throw new IllegalArgumentException();
this.attributes = attributes;
}
Are my assumptions correct?