[OJB-developers] multiple classes mapped to single table request for comments
Brought to you by:
thma
From: Matthew B. <ma...@so...> - 2002-06-09 16:27:17
|
There are a bunch of scenarios that make mapping multiple objects to a single table rather tricky. Class A mapped to MultiTable Class B mapped to MultiTable Class C extends A mapped to MultiTable Class D extends B mapped to MultiTable So we have completely unrelated objects mapped to the table, as well as classes with their extents mapped to the same table. When someone queries for A, they should get all A. When someone queries for B, they should get all B. When someone queries for C they should get all C and all A. When someone queries for D they should get all D and all B. Now if we look at the code, we see that an RsIterator is built which holds the resultset and materializes objects as they are asked for with .next() Problem is, hasNext doesn't materialize the object, it just checks if the resultset has another element, it doesn't know what that element is. SO if someone writes a query for A, OJB will load up all elements in MultiTable (all A, B, C, D) and the RsIterator will be the disciminator, throwing out non-A classes. So that gets to the problem: Imagine the resultset holds (in this order) ABCADAABB hasNext will return true while next() will return a null object. I see two solutions: 1. Make hasNext actually materialize the object to find out whether it is a valid class type for the query, then return true/false based on that. It would do that by calling an internal next() until it found a valid candidate. PROS: only changing RsIterator, should work for all cases. CONS: possibly slow as you could have a lot of records in that table and we'd have to crawl through all of them looking for a valid candidate. Counts based on iterators would not be right because resultset would contain non valid candidates. RsIterator code would become complex. 2. Change the select queries for classes that have the 'ojbConcreteClass' column mapped to append a where discriminator based on classtype. So a query for all D in the above example would include the following WHERE clause WHERE MultiTable.CLASS_TYPE='D' OR MultiTable.CLASS_TYPE='B' PROS: Most efficient. No checking necessary to see if the materialized object is an instance of what was requested. Iterators Would only contain valid candidates and thus size and other methods would work as expected. CONS: Bigger change, more change to SQL generation code; where clause would be slower? Seems to me #2 is probably the right thing to do. Please vote as I would like to change and checkin today. |