From: Gavin_King/Cirrus%<CI...@ci...> - 2002-06-04 04:05:24
|
> I think the meaning got lost in my verbiage here. What I meant to suggest > was that cascading be available via overloaded methods such as: > > save/update(Object o, boolean cascade); //I wouldn't include cascade delete But how would you know where to stop? (is it a shallow or deep cascade?) How would you know _which_ properties to cascade and which properties to ignore? I think this would be useful only for object models with a very tree-like structure where you can always cascade a whole "branch". The mapping-file and callback approaches both allow "selective" cascades to some relationships but not others. PersistentLifecycle already provides callbacks that let the application cascade save() and delete(). It seems clear to me now that we also need to provide an update() callback. I'm thinking of deprecating PersistentLifecycle and replacing it with: package cirrus.hibernate; public interface Lifecycle { public boolean save(Session s) throws .....; // used to be create() public boolean update(Session s) throws ....; // called from update() public boolean delete(Session s) throws ....; public void load(Session s); // notice I got rid of store() } (The return value allows the object to veto the requested operation transparently to the rest of the application - its like a shortcircuit.) What do people think of this suggestion? I think its a big improvement. > The other problem I see with the cascade all option is that cascade delete > is only viable in some cases, whereas cascade save and update are viable in > almost all cases. fair enough, its clear that we do need the various cascade options that I was originally thinking of: cascade="none" cascade="all" cascade="delete" cascade="update" cascae="save" cascade="save|update" cascade="save|delete" > What I am really suggesting here is that cascade delete be the *only* > cascade type tag - all other cascades to be determined by the overloaded > method calls. This is because delete is the only operation where semantic > knowledge of the Parent-Child dependencies determines how the operation is > executed. Thats fair enough, but not everyone would agree that the mapping file may only contain stuff thats part of the object model. I'm happy to provide maximum flexibility here and let people use exactly which subset of functionality fits their philosophical approach. > Personally, I like the idea of this being a separate method (persist), > since save/update/insert all lose their meaning when they cascade to other > operations. From your example where foo and baz need updating and bar > needs saving. > > foo -> bar -> baz > > By calling update(foo), I implicitly call update(bar). Instead of an > error, the method is redirected to save(bar). Yet if I call save(bar) > directly I would get an error. Why? Instead, I would push > save/update/insert off center stage - people can use them if they know > exactly what operation they want to perform - and instead use persist() as > the normal case, which doesn't imply any one operation. Save/update/insert > would then cascade to only their own operations, allowing optimization > since they don't have to figure out what operation to perform. Actually update() in its current implementation has semantics sooo close to your persist() that its not worth providing two seperate methods. Arguably update() is badly named but lets make the question of naming a seperate question. eg. session.update(newObject) actually calls session.save(newObject) if the id is null. Its silly to have two seperate methods that 1. update the object if its id is non-null otherwise save it 2. update the object if its id is non-null otherwise throw an exception > Insert is a tough one, since it is difficult to tell if a referenced object > that has an assigned id was meant to be inserted or updated. The only way > to tell is an SQL error or EXISTS check. You could stipulate that > persist() only does saves and updates, no inserts. Yeah - basically insert() has turned out to be an operation available at the "top" level only. I doubt that this will really be a huge issue to most users. Gavin. |