ojb needs the pk to be unique within a hierarchy. Identity#equals just checks for the toplevel class not the real class, that's why. changing this behaviour is delicate.
afaik the tutorial simply uses the super-reference (with the same pk) but it does _not_ use extent-definitions. so the classes do not belong to the same hierarchy and thus an identical pk does not hurt.
jakob
Justis Peters wrote:
Hi Jakob,
The answers you provide Burt imply that it is possible to do exactly what I am trying to do. What is it that I am doing wrong? My test cases seem to follow exactly what Burt is doing.
Also, I do not understand your comment about the primary key needing to be unique. The tutorial specifically recommends using the same primary key for both, in order to link the rows together. In the case we are discussing below, the data in A_TABLE is not an object referenced by B_TABLE -- it is actually the data that comprises the remainder of B_TABLE. It is just stored in A_TABLE instead, to avoid redundancy and to allow for selecting from the entire extent when using tools other than OJB.
Am I misunderstanding something? I realize that the current implementation of the super-reference does not do what I am requesting. It seems to me, though, that it should eventually do this.
Thanks in advance for your reply!
Sincerely yours, Justis Peters Oculan Corp. [EMAIL PROTECTED]
Jakob Braeuchi [EMAIL PROTECTED] wrote:
hi burt,
1.) this is partly correct:
three queries will be executed to load the extents. problems could arise when materializing the objects. ojb assumes that a primary key is _unique_ within a class hierarchy. if this is not true the wrong object will be returned. this could be solved here by _not_ using the pk in super-reference.
2.) same problem as in 1.)
3.) that's true atm.
4.) also true if the auto-settings of the reference descriptor are not set to false.
jakob
BURT, RANDALL (CONTRACTOR) wrote:
Jumping in late, but its germane to what I'm working on. So, if I read what everyone is saying correctly, the following:
<class-descriptor class="polymorphtest.InterfaceA"> <extent-class class-ref="polymorphtest.A" /> <extent-class class-ref="polymorphtest.B" /> <extent-class class-ref="polymorphtest.C" /> </class-descriptor>
<class-descriptor class="polymorphtest.A" table="A_TABLE">
<extent-class class-ref="polymorphtest.B" />
<field-descriptor name="id" column="ID" jdbc-type="INTEGER" primarykey="true" autoincrement="true" />
<field-descriptor name="someValueFromA" column="VALUE_" jdbc-type="INTEGER" />
</class-descriptor>
<class-descriptor class="polymorphtest.B" table="B_TABLE">
<field-descriptor name="id" column="ID" jdbc-type="INTEGER" primarykey="true" autoincrement="true" />
<field-descriptor name="someValueFromB" column="VALUE_" jdbc-type="INTEGER" />
<reference-descriptor name="super" class-ref="polymorphtest.A">
<foreignkey field-ref="id" />
</reference-descriptor>
</class-descriptor>
<class-descriptor class="polymorphtest.C" table="C_TABLE">
<field-descriptor name="id" column="ID" jdbc-type="INTEGER" primarykey="true" autoincrement="true" />
<field-descriptor name="someValueFromC" column="VALUE_" jdbc-type="INTEGER" />
</class-descriptor>
does not do what I would expect? :
1. Queries for collections of InterfaceA would give me all the A's, B's, and C's.
2. Queries for collections of A's would give me A's and B's, but the A's would be only those rows in A_TABLE that did not have matching keys in B_TABLE.
3. If I queried for an A, but there is a B that matches, I'd get a B and not just an A.
4. Anytime B's are materialized, they would have their inherited properties from the super class A populated.
Sorry if this is a re-hash, but I'm getting a little confused ATM. Thanks for any clarifications.
-----Original Message----- From: Jakob Braeuchi [mailto:[EMAIL PROTECTED] Sent: Friday, October 17, 2003 12:09 PM To: OJB Users List; Thomas Mahler; Armin Waibel Subject: Re: Wrong class materialized when selecting from an extent mapped to a multi-table join
hi justis, wallace,
this problem is caused by Identity#equals noch checking objectsRealClass . consider the following situation: a select for InterfaceA fires 2 selects
SELECT A0.VALUE_,A0.ID FROM A_TABLE A0
retrieving Table_A objects with ids 1 and 2
SELECT A0.VALUE_,A0.ID FROM B_TABLE A0 INNER JOIN A_TABLE A1 ON A0.ID=A1.ID
retrieving Table_B object with id 1
when building the objects from the resultset in RsIterator#getObjectFromResultSet an identity is built from the row and looked up in the cache. the object (id = 1) from table_B is considered to be in the cache because the topLevelClass (InterfaceA) and the pk (1) matches !
this problem could be solved by also checking the objectsRealClass in Identity#equals. i remember there was quite a big discussion about Identity, so i'm not sure if this is a correct soluion ??
another solution could be to use a dedicated column to refer to the super-class in the reference-descriptor. this would avoid the pk-clash in the cache.
another way is to completly avoid using extents and super-references ;)
<class-descriptor class="polymorphtest.InterfaceA"> <extent-class class-ref="polymorphtest.A" /> <extent-class class-ref="polymorphtest.B" /> </class-descriptor>
<class-descriptor class="polymorphtest.A" table="A_TABLE">
<field-descriptor name="id" column="ID" jdbc-type="INTEGER" primarykey="true" autoincrement="true" />
<field-descriptor name="someValueFromA" column="VALUE_" jdbc-type="INTEGER" />
</class-descriptor>
<class-descriptor class="polymorphtest.B" table="B_TABLE">
<field-descriptor name="id" column="ID" jdbc-type="INTEGER" primarykey="true" autoincrement="true" />
<field-descriptor name="someValueFromB" column="VALUE_" jdbc-type="INTEGER" />
<reference-descriptor name="super" class-ref="polymorphtest.A">
<foreignkey field-ref="id" />
</reference-descriptor>
</class-descriptor>
jakob
Justis Peters wrote:
Hi All!
Just a couple weeks ago I started using OJB, and I am
extremely impressed. My gratitude goes to all who put in the work to make it possible.
Upon converting some of the more complicated parts of my
object model, I encountered a strange issue. Here is the bug I attempted to submit to scarab. Apparently, scarab is having problems. At first, it assigned an ID to my issue that was already assigned to another issue, so I can't retrieve it. Now, it won't let me enter new issues and keeps directing me to the query page isntead.
Anyhow, here is the summary of the bug. Any help would be
appreciated:
============================================================== ============
When selecting an entire extent from a parent class, the
behavior varies depending on whether you are using multi-table joins or distinct tables for each class. Everything seems to work correctly if you use distinct tables for each class. If you are using multi-table joins, however, your objects are not always materialized as the class you would expect. Here is the scenario for the test case I made:
Object model ------------ - public interface InterfaceA - public class A implements InterfaceA - public class B extends A implements InterfaceA
Test case 1
-----------
- start with a new JVM
- select all from extent InterfaceA.class, loop through and
display the class for each
- select all from extent A.class, loop through and display
the class for each
- select all from extent B.class, loop through and display
the class for each
Test case 2
-----------
- restart with a new JVM
- select all from extent B.class, loop through and display
the class for each
- select all from extent A.class, loop through and display
the class for each
- select all from extent InterfaceA.class, loop through and
display the class for each
Results
-------
- If using distinct tables for each class (see schema1.sql
and repository_user1.xml), both test cases materialize all objects as the correct subclass and returns the expected instances with the appropriate queries.
- If using multi-table joins (see schema2.sql and
repository_user2.xml), test case 1 displays everything as being class "A", even if it was a "B". Instances of "B" are retrieved and displayed twice in the queries for "InstanceA". Once you get to querying for "B", it turns up absolutely no instances. I imagine this is because it is cached. Test case 2 correctly materializes the objects a "B" and "A", depending on which table they appear in; when you query against InterfaceA.class, however, it still displays the duplicates for instances of "B".
For convenience in debugging, I have written a command-line
test that lets you choose the order in which the extents are retrieved and displayed. You can run it by doing:
java polymorphtest.PolymorphTest 0 1 2 (test case 1) OR java polymorphtest.PolymorphTest 2 1 0 (test case 2)
All the related classes, schemas, and O/R mappings are
attached to this bug. Please contact me if you need help reproducing the errors.
================================================================
I don't want to send the attachments to the whole list, but
I will be glad to email the tarball to whomever requests it. Thanks in advance for your help!
Sincerely, Justis Peters Oculan Corp. [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
