I have a Map<String,FoobarMap> which is stored the a table "foobar_map". But I am having a problem deleting entries from the map and causing the row from the table to also be deleted.
Code:
<class name="com.domain.data.Head" table="head">
<id name="headId" type="long" column="head_id">
<generator class="native" />
</id>
<property name="randomProperty" not-null="true" type="long" column="random_property_id"/>
<map name="foobarMap" cascade="all">
<key column="head_id" not-null="true"/>
<map-key column="name" type="string"/>
<one-to-many class="com.domain.data.FoobarMap"/>
</map>
</class>
<class name="com.domain.data.FoobarMap" table="foobar_map">
<id name="foobarMapId" type="long" column="foobar_map_id">
<generator class="native" />
</id>
<many-to-one name="head" column="head_id" not-null="true" insert="false" update="false"/>
<!-- Map key -->
<property name="name" not-null="true" type="string" column="name" insert="false" update="false"/>
<property name="otherDataOne" not-null="false" type="integer" column="other_data_one"/>
<property name="description" not-null="true" type="string" column="description"/>
</class>
I assign/create in the map with:
Code:
FoobarMap foobarMap = new FoobarMap();
foobarMap.setName("the_name");
foobarMap.setDescription("hello");
foobarMap.setOtherDataOne(Integer.valueOf(1));
Head head = (Head) hsession.load(Head.class, new Long(1));
head.getFoobarMap.put(foobarMap.getName(), foobarMap);
hsession.save(foobarMap);
Okay at this point all is well and good, the cascade has saved the data in the map table, I did not need to call hsession.save(foobarMap) at all to create new persited instances.
Now I wish to delete from the table, I do this with:
Code:
Head head = (Head) hsession.load(Head.class, new Long(1));
Iterator it = head.getFoobarMap().keySet().iterator();
while(it.hasNext()) {
String thisName = (String) it.next();
FoobarMap foobarMap = (FoobarMap) head.getFoobarMap().get(thisName);
boolean remove = true;
if(externalTest(head, foobarMap))
remove = false;
if(remove) {
it.remove();
// This line throws and exception org.hibernate.NonUniqueObjectException
// a different object with the same identifier value was already associated with the session: [com.domain.data.FoobarMap#0]
// hsession.delete(foobarMap);
}
}
// Sometimes I optionally add new entries into the head.getFoobarMap().put() here
// those additions work correctly. But because the delete part above is not working
// they accumulate rows.
// I am hoping this will cascade delete, but it does not.
hsession.update(head);
I believe the documentation for my situation is described at
http://www.hibernate.org/hib_docs/v3/re ... tional-12m
It says unusual and not really recommended. But I dont understand why, since I have a nice compact 2 table situation. With an extra could of columns in the child-table (Map.Entry) to group the entries back to the parent (Map).
There are some extra options like update="false" since I was trying to make the values to some columns immutable, forcing me to make a new instance if I wanted to rename the key part of the Map.