From: Gavin_King/Cirrus%<CI...@ci...> - 2002-08-31 01:43:26
|
Yeah, this is interesting. This problem is specific to one-to-one associations. Firstly, yes there is a way, simply call save() for the parent before calling save() for the children. Hibernate *always* inserts rows in the same order the objects were saved. However, there is a problem for saves cascaded through cascade="all". The problem is that one-to-one associations are by nature bidirectional so in the absence of any other metadata we wouldn't know whether the foreign key was from "parent" to "child" or vice-versa. Currently Hibernate just treats one-to-one associations like many-to-one (ie. assumes the foreign key runs from "parent" to "child" and so inserts the child row first). (Saves cascaded via Lifecycle callbacks could also suffer the same problem, but theres not much we can do about that.) In the case of many-to-one relationships, there is another trick used to ensure no constraint violations occur, even in the case of circular foreign key references. Hibernate is able to insert a null into the foreign key column and then update it later. Unfortunately we can't use this technique with one-to-ones because the foreign key constrains the primary keys. So the general solution to this problem must involve adding an attribute to the <one-to-one> element to tell Hibernate which direction the foreign key constraint points and hence whether the association should be cascaded before or after the parent is saved. (This would also let as create the foreign key from the SchemaExport tool.) So we should add something like: <one-to-one name="child" constrained="outward"/> and a matching <one-to-one name="parent" constrained="inward"/> or something like that.... |