I enclose the best mapping I think I've managed to put together. My problem at the moment is saving my transient objects with a single save() call and letting cascade=all do the work.
I am struggling to understand first what to call the relationship, so I can then apply the appropiate section of the hibernate manual at it.
I think the relationship is actually "one-to-many" as in one row in mytable_container references many rows in mytable_thingy (but under different joining columns from mytable_container).
However such a hibernate config mapping (according to XML DTD assitance in Eclipse does not even let me specify the column="" attribute, which can't be right at all, as the joinging column name in mytable_container is an important thing to need to specify).
To describe how the load would work:
Hibernate can either do a SELECT on the mytable_container and 1 or 3 selects on mytable_thingy during the load or it can load with a single join (as long as it re-opens the mytable_thingy under an alias for each thingyOne, thingyTwo, thingyThree).
SELECT
c.mytable_container_id,
t1.value_integer,
t1.value_string,
t2.value_integer,
t2.value_string,
t3.value_integer,
t3.value_string
FROM
mytable_container AS c,
mytable_thingy AS t1,
mytable_thingy AS t2,
mytable_thingy AS t3
WHERE
c.mytable_container_id = :priKey_I_want AND
c.thingy_one = t1.mytable_thingy_id AND
c.thingy_two = t2.mytable_thingy_id AND
c.thingy_three = t3.mytable_thingy_id;
The Thingy's are fully managed inside Container object, they never exist in their own right. For every container row there is between zero and 3 thingy rows that, the container row effectively 100% owns.
In the hibernate docs there is a attribute unsaved-value="", from the documentation this is already set to a sane default. I'm happy (and my SQL database is happy) that the value of 0 never exists in either a runtime object or a persisted record.
Unless of course the runtime object is new and transient and about to be persisted. I'm expecting hibernate to work out that "This is a new instance of this object" and therefore do INSERTs. I also expect it to work out that my Container object was the result of a previous load and when I replaced a Thingy object to also do the DELETE of the now orphaned row.
Is this possible with hibernate ?
My best effort at a mapping file:
Code:
<class name="com.company.Container" table="mytable_container">
<id name="id" type="long" column="mytable_container_id">
<generator class="native" />
</id>
<many-to-one name="thingyOne" not-null="false" unique="true" column="thingy_one" cascade="all" />
<many-to-one name="thingyTwo" not-null="false" unique="true" column="thingy_two" cascade="all" />
<many-to-one name="thingyThree" not-null="false" unique="true" column="thingy_three" cascade="all" />
</class>
<class name="com.company.Thingy" table="mytable_thingy">
<id name="id" type="long" column="mytable_thingy_id">
<generator class="native" />
</id>
<property name="someValue" type="int" column="value_integer" />
<property name="someString" type="string" column="value_string" />
</class>