Re: [OJB-developers] Question regarding extents
Brought to you by:
thma
From: Thomas M. <tho...@ho...> - 2002-05-31 13:30:06
|
Hi again, Matthew baird wrote: > I'm looking through the code trying to thoroughly grok how extents are > supported, and I have to admit I'm a little bit puzzled :) I was > wondering if someone out there could comment on my understanding of how > things work: > > Consider having two objects mapped to the same table, but they one > doesn't inherit from the other. To be concrete, we have OperatingUnit > and EnterpriseUnit. > > If I execute an OQL query "select unit from > com.somecompany.OperatingUnit" I would expect to get back all the > operatingunits and none of the enterpriseunits. To support that, I've > included an ojbConcreteClass mapping for each of the unit types. > > OJB does it's thing and finally ends up calling the .next() on the > RsIterator, during which OJB will call getObjectFromResultSet which will > eventually call readObjectFrom > > readObjectFrom then checks the ojbConcreteClass attribute, but can't > really use this as a discriminator since it doesn't know what you asked > for (for instance, the first row in the UNIT table is an enterprise > unit, and I asked for operatingunits) so it tries to build the > EnterpriseUnit using the query results of the OperatingUnit. > > If EnterpriseUnit doesn't have the same fields mapped in the same order > as OperatingUnit, building the new instance of the object will throw an > exception. the exception makes its way back to the .next() routine where > it is caught as an Exception and rethrown as a NoSuchElementException > which is NOT caught in getCollectionByQuery > > getCollectionByQuery is extent aware, and is ready to deal with having > object materialized that don't match what was asked for > > if ((itemClass.equals(candidate.getClass())) > || (Proxy.isProxyClass(candidate.getClass())) > || (candidate instanceof VirtualProxy)) > > is the important peice of code however, this code is unlikely to > actually be called because Object candidate = i.next(); is probably > going to throw a NoSuchElementException exception. > > There are a couple other places where we load the object, check the type > and try to materialize one of those objects. Using the new row[] array > instead of the resultset means we have to be aware of the ordering of > results (we can't get them by name) which causes a problem with 2 > objects mapped to the same table with different order of mappings. I can > live with that, but the materialization of an extent object with extra > attributes failing because row[] doesn't contain all those values is not > good. > I agree. We'll have to improve the "mapping on one table"-stuff. (We'll also need support for the third possible mapping of inheritance hierarchies, where attributes may come from different tables.) > If you grokked all that, here's a potential solution: > > when creating the select SQL, if more than one object is mapped to the > table, either load the union of all the fields that *could* be used > dependent on object type, then store them by name in a hashmap (or come > up with a lighter solution to get the columns by name). Then you would > be guaranteed that the actual object could be created if need be. This > solution would allow for people to query on base class and still get > back base and sub classes all mapped to same table. > I think this is the way to go. > Other solution would be to somehow append the objConcreteClass > discriminator to the where clause, but that would not allow for loading > subclasses as base objects, so I don't think it's a good solution. > I agree. cheers, Thomas > Comments? > > > > > > > > > > > ------------------------------------------------------------------------ > *Do You Yahoo!?* > Yahoo! <http://rd.yahoo.com/welcome/*http://fifaworldcup.yahoo.com> - > Official partner of 2002 FIFA World Cup |