From: Paul S. <pau...@ne...> - 2002-02-14 09:04:07
|
Hi Gavin, some comments below, but I think the main issues here are (1) the value of associations over just collections, and (2) how you might implement this either in a product or as a work-around. Below are my observations and *opinion*, I'd welcome other input on this. IMO associations are key - the fact that you happen to implement them using collections in Java is a mere detail. We work on an object model, then translate that into code. The kinds of things you mention might be possible, but I cannot see *why* you would want to do them. Your statement about such a concept being alien to idiomatic Java to me seems to be putting the horse before the cart. While true, I think that it loses sight of what we're building - for me at least that's the object model. Anyway, more comments below. PaulS :) Gavin_King/Cirrus%CI...@ci... wrote: > Hi Paul, > > Hibernate's associations are fundamentally uni-directional. The reason for > this is that Java object references and the Java collections framework only > permit navigation in one direction ie. dereferencing an object reference, > or retrieving an object from a collection. There is no way for an object to > determine if it belongs to a collection, or what other objects hold > references to it. It is _possible_ to implement a bidirectional association > in Java as a seperate class. At one (very early) stage there was even > something exactly like this in Hibernate. I threw the concept away because > it is just too alien to idiomatic Java. > > Now, it *would* be possible to do something like you suggest, and have two > seperate associations, which happen to map to the same database column. The > problem with that is that such a solution is very, very bugprone. If your > Master throws away the Set it was holding details in, and creates a new > Set, the details objects will still have references to the same Master. > When we come to persist this broken structure, the results will be > nondeterministic. There are ways to do this, and all the commercial O/R tools that I've used support this. Basically the association is "managed" from one end when it comes to persisting the association - and it's straightforward to tell when things are screwy. > Well, actually I lie. It *is* deterministic. The one-to-many association > always wins over the many-to-one association in the current implementation. > Those semantics are not guaranteed under a future, more efficient, > implementation of collections. > > There is _no_ way to fix this without creating new API classes that intrude > upon the business model. Or otherwise annoy you. For example, you wouldnt I don't see why this would be the case. Could you elaborate? > be able to pass collections seamlessly from one object to another and stuff > like that.... I don't see the problem. Your code (i.e. not Hibernate, the users code) is still responsible for making sure all the persistent objects point to the right places. This is true without persistence, and I wouldn't expect the persistence layer to do this for you - that would be intrusive. > If you really need a bi-directional association (if bi-directional > associations were really that essential then OO languages would have them - I won't touch that one. > and none do) then you can do any of the following > > 1. Detail has a many-to-one association to Master. Master can select its > Details using a query ( perhaps lazily, perhaps from > PersistentLifecycle.load() ) > > FROM detail IN CLASS pkg.Detail WHERE detail.master.id = ? Isn't this what happens anyway? > and then put them in a transient collection. (My favored solution.) > > 2. Master has a one-to-many association to Detail. Detail can get its > Master using a query (not efficient). > 3. Master has a one-to-many association to Detail. Master can set transient > backpointers on each Detail from PersistentLifecycle.load() > > All these solutions run the same risk of bugs as if they would be > implemented in the persistence layer. The difference is: they would be > application bugs - the persistence layer will still behave > deterministically. Yep - and that's fine. And if you wanted to you *could* do a consistency check quite transparently. There's actually huge advantages in being able to do that. > > I _guess_ we could fix the Schema generator to detect and remove duplicated > column names and let you do what you want to do .... It won't *break* > Hibernate, and it _does_ have quite str8forward semantics in this version > (ie. the bit about the collection end wining.) But if we fix it I would > much rather leave that feature undocumented. What do others think? |