can i understand this to mean that OJB (at least in CVS) now properly
handles multilevel-abstract-inheritance-hierarchies (whew!) for both the
extent aware iterator *and* collections?
-ryan
On Mon, 2002-09-16 at 15:47, Jakob Braeuchi wrote:
> hi chris,
>
> i just commited support for multilevel hierarchies.
> please have a look at it.
>
> jakob
>
> ----- Original Message -----
> From: "Jakob Braeuchi" <[EMAIL PROTECTED]>
> To: "OJB Users List" <[EMAIL PROTECTED]>
> Sent: Monday, September 16, 2002 9:26 PM
> Subject: Re: Object Hierarchies Again
>
>
> > hi chris,
> >
> > what about multilevel hierarchies in getIterator/CollectionByQuery ?
> > do you have a fix for these methods too.
> >
> > jakob
> >
> > ----- Original Message -----
> > From: <[EMAIL PROTECTED]>
> > To: "OJB Users List" <[EMAIL PROTECTED]>
> > Sent: Monday, September 16, 2002 4:30 PM
> > Subject: Re: Object Hierarchies Again
> >
> >
> > > hi chris,
> > >
> > > i remember those posts and i asked the person for a new fix based on
> > current
> > > implementation of pb. pb now supports extent aware iterators (not
> > multilevel
> > > though).
> > > i also had some mails with matthew regarding multilevel hierarchies. as
> > soon
> > > as time permits (i'm working on a new job now) i'll see how i can
> > integrate
> > > your fix.
> > >
> > > thanks a lot
> > > jakob
> > >
> > > > Hi all,
> > > >
> > > > You may remember a few posts recently regarding correct searching of
> > > > object hierarchies, in particular ones which contain a number of
> > > > abstract classes between the root and concrete subclasses. In a
> > > > nutshell, the PB does not seem to check for abstract classes beyond
> one
> > > > level, ie it assumes that there will be only one abstract layer before
> > > > concrete classes are hit. This didn't work for us as we have two or
> > > > three abstract class layers before concrete subclasses.
> > > >
> > > > No useful feedback appeared, and a solution was posted which almost
> > > > solved the problem. However it didn't quite work, as references and
> > > > collections were not resolved (the app in question didn't need them).
> > > > There was a further problem relating to multiple classes mapped to a
> > > > single table. Briefly, OJB retrieves a whole row, and resolves the
> class
> > > > to materialize later. This caused us problems because in checking for,
> > > > say, class A, all data were retrieved on a search for class A (via
> PK),
> > > > but the data from the row were actually from class B (mapped to the
> same
> > > > table). So OJB tried to materialise an object of class A with data for
> > > > an object of class B. A workaround (which was simpler to come up with
> > > > than to track the bug down!!) is to get the Class Descriptor for class
> B
> > > > when the data are first retrieved, and pass *that* class descriptor to
> > > > retrieveReferences/retrieveCollections.
> > > >
> > > > Clear as mud? Good. :-)
> > > >
> > > > Anyway, I've included the code fixes at the bottom of this mail -
> > > > basically two methods for PersistenceBrokerImpl.java. The first,
> > > > getDBObject, is modified from the original. The second, checkExtents,
> > > > handles the iterative search down the class hierarchy, and uses
> > > > getDBObject to build the concrete data.
> > > >
> > > > Please note this was done on OJB 0.9.2, but as far as I can see the PB
> > > > in 0.9.4 is not a whole lot different. Haven't checked the 0.9.5
> source.
> > > > Whilst it will be nice to try out the refactorings, I'm sticking with
> > > > 0.9.2 for now 'cos what we have works (so far) with it and I think
> I'll
> > > > wait a little while until things settle down a bit more with the
> latest
> > > > releases. Not that I'm a cautious kind of person, you understand :-)
> > > >
> > > > I'm still surprised that no-one else has come across this issue
> before.
> > > > Does no-one really have any problems with hierarchies containing more
> > > > than one level of abstraction? Anyway, hope the code below helps a
> > > > little if you come across this problem in your travels across O/R
> > > > mapping land...
> > > >
> > > > Cheers,
> > > >
> > > > Chris
> > > >
> > > >
> > > > ----------- code follows......snip if not interested --------------
> > > >
> > > >
> > > > private Object getDBObject(Identity oid) throws
> > > > ClassNotPersistenceCapableException
> > > > {
> > > > Class c = oid.getObjectsRealClass();
> > > > if (c == null) {
> > > > c = oid.getObjectsClass();
> > > > }
> > > >
> > > > ClassDescriptor cld =
> descriptorRepository.getDescriptorFor(c);
> > > >
> > > > Object newObj = null;
> > > >
> > > > //if the class is not an interface or abstract, check it
> > > > directly as it must be concrete
> > > > if (!cld.isInterface()) {
> > > > //NB materializeObject only fills non-reference
> fields...
> > > > newObj = dbAccess.materializeObject(cld, oid);
> > > > if(newObj != null && oid.getObjectsRealClass() == null) {
> > > >
> > > > oid.setObjectsRealClass(newObj.getClass());
> > > > }
> > > >
> > > > }
> > > >
> > > > //if we get to here without an object, it may be an interface
> or
> > > > abstract
> > > > if(newObj == null && cld.isExtent()) {
> > > >
> > > > newObj = checkExtents(oid,cld);
> > > > }
> > > >
> > > > if(newObj != null) {
> > > >
> > > > //first cache it so references back to it can be matched
> > > > objectCache.cache(oid, newObj);
> > > >
> > > > //got a partially filled object - now get references and
> > > > collections...
> > > > /*
> > > > * CLEWINGTON
> > > > * NB can cause problems with multiple objects mapped to
> one
> > > > table, as follows:
> > > > *
> > > > * if the class searched on does not match the retrieved
> > > > class, eg a search on an
> > > > * OID retrieves a row but it could be a different class
> (OJB
> > > > gets all column values),
> > > > * then trying to resolve references will fail as the
> object
> > > > will not match the Class
> > > > * Descriptor.
> > > > *
> > > > * To be safe, get the descriptor of the retrieved object
> > > > BEFORE resolving refs
> > > > */
> > > >
> > > > Class newObjClass = newObj.getClass();
> > > > ClassDescriptor newObjCd =
> > > > descriptorRepository.getDescriptorFor(newObjClass);
> > > > retrieveReferences(newObj, newObjCd);
> > > > retrieveCollections(newObj, newObjCd);
> > > >
> > > > }
> > > >
> > > > return newObj;
> > > > }
> > > >
> > > > /**
> > > > * Method to work down the class hierarchy until a concrete
> object
> > > > is found.
> > > > * Used mainly by getDBObject.
> > > > *
> > > > * @param oid - OID of the object to check
> > > > * @param cld - the Class Descriptor of the class to be checked
> > > > (will be either an interface
> > > > * or abstract class)
> > > > *
> > > > * @return Object - the concrete object found, or null if none are
> > > > found
> > > > */
> > > > private Object checkExtents(Identity oid, ClassDescriptor cld)
> > > > {
> > > > Object newObj = null;
> > > > Vector extentClasses = new Vector();
> > > >
> > > > //detailed debug info...
> > > > logger.debug("getExtentDBObject called....");
> > > > logger.debug("class: " + cld.getClassOfObject().getName());
> > > > logger.debug("object ID: " + oid.toString());
> > > > logger.debug("class " + cld.getClassOfObject().getName() + "
> is
> > > > abstract - getting subclasses...");
> > > >
> > > > extentClasses = cld.getExtentClasses();
> > > >
> > > > //search the subclasses (recurse if necessary via getDBObject)
> > > > until we find a concrete match
> > > > for(int i=0; i < extentClasses.size(); i++) {
> > > >
> > > > //make sure the class descriptor we finish with matches a
> > > > subclass, not the abstract one..
> > > > cld = descriptorRepository.getDescriptorFor((Class)
> > > > extentClasses.get(i));
> > > > logger.debug("subclass: " +
> > > > cld.getClassOfObject().getName());
> > > >
> > > > //try and get an object - set the OID class to be the
> extent
> > > > class and search again..
> > > > oid.setObjectsRealClass(cld.getClassOfObject());
> > > > newObj = getDBObject(oid);
> > > > if(newObj != null) {
> > > >
> > > > if(oid.getObjectsRealClass() == null) {
> > > >
> > > > oid.setObjectsRealClass(newObj.getClass());
> > > > }
> > > >
> > > > //done so jump out
> > > > break;
> > > > }
> > > > }
> > > >
> > > > return newObj;
> > > > }
> > > >
> > > > ------------------- end ----------------------------
> > > >
> > > >
> > > >
> > > >
> > > > --
> > > > To unsubscribe, e-mail:
> > <mailto:[EMAIL PROTECTED]>
> > > > For additional commands, e-mail:
> > <mailto:[EMAIL PROTECTED]>
> > > >
> > >
> > > --
> > > GMX - Die Kommunikationsplattform im Internet.
> > > http://www.gmx.net
> > >
> > >
> > > --
> > > To unsubscribe, e-mail:
> <mailto:[EMAIL PROTECTED]>
> > > For additional commands, e-mail:
> <mailto:[EMAIL PROTECTED]>
> > >
> >
> >
> > --
> > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
> >
>
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
--
Humans are the unfortunate result of a local maximum in the
fitness landscape.
www.ryanmarsh.com
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>