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.... |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-08-31 03:44:28
|
>That sounds perfect. Any chance of this happening in the near future? >I'm sort of at a dead end at the moment because of this. Yeah, its easy enough to implement. I'll have a look at it today if you like. >I was hoping to use the Lifecycle interface to get around this problem, >but it looks like you only get callbacks before the event and not after >the event. Have you considered extending Lifecycle to support this? Its very difficult to strike a balance with the Lifecycle interface. Theres all kind of events that could be useful but, on the other hand, we want the interface to be as simple as possible and we don't want to let assumptions about the internal dynamics of the session implementation "seep" into the API. The other thing is that its very difficult to change callback interfaces (you can deprecate methods but never add new ones). So Hibernate tries to stay as far away as possible from these kind of frameworky solutions to problems. I think its better to address this particular issue as proposed.... Of course, I am very open to other people's opinions on this. |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-08-31 14:01:37
|
This is now implemented as an optional attibute constrained="true|false" on the <one-to-many> element. |
From: Mark W. <mor...@SM...> - 2002-09-01 20:51:13
|
Gavin_King/Cirrus%CI...@ci... wrote: >This is now implemented as an optional attibute constrained="true|false" on >the <one-to-many> element. > Don't you mean the <one-to-one> element? Is constrained="false" equivalent to the way it currently works (and I assume will remain the default)? Thanks, -Mark |
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-09-02 00:56:46
|
> Don't you mean the <one-to-one> element? Of course. > Is constrained="false" equivalent to the way it currently works (and I > assume will remain the default)? yes. |
From: Mark W. <mor...@SM...> - 2002-08-31 02:06:15
|
Gavin_King/Cirrus%CI...@ci... wrote: >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.... > > That sounds perfect. Any chance of this happening in the near future? I'm sort of at a dead end at the moment because of this. I was hoping to use the Lifecycle interface to get around this problem, but it looks like you only get callbacks before the event and not after the event. Have you considered extending Lifecycle to support this? Thanks, -Mark |