You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by "Phillips, Joshua (NIH/NCI)" <ph...@mail.nih.gov> on 2004/07/09 19:18:36 UTC

OJB extents, multiple joined tables

When I query for all instances of class X, I expect to get all instances of
class X and all instances of any subclass of X. But, in the following
scenario, this isn't working.

Suppose the following:
  - BaseImpl implements BaseInterface
  - AInterface extends BaseInterface
  - BInterface extends BaseInterface
  - AImpl implements AInterface
  - AImpl extends BaseImpl
  - BImpl implements BInterface
  - BImpl extends BaseImpl

Then the class-descriptor elements for this model should look like this:

<class-descriptor class="BaseInterface">
   <extent-class class-ref="BaseImpl" />
   <extent-class class-ref="AInterface" />
   <extent-class class-ref="AImpl" />
   <extent-class class-ref="BInterface" />
   <extent-class class-ref="BImpl" />
</class-descriptor>

<class-descriptor class="AInterface">
   <extent-class class-ref="AImpl" />
</class-descriptor>

<class-descriptor class="BInterface">
   <extent-class class-ref="BImpl" />
</class-descriptor>

<class-descriptor
	class="BaseImpl"
	table="BASE">

   <extent-class class-ref="AImpl" />
   <extent-class class-ref="BImpl" />
	
	<field-descriptor
		name="id"
		column="ID"
		jdbc-type="BIGINT"
		primarykey="true"/>
		
</class-descriptor>

<class-descriptor
	class="AImpl"
	table="A">
	
	<field-descriptor
		name="id"
		column="ID"
		jdbc-type="BIGINT"
		primarykey="true"/>

	<field-descriptor
		name="superId"
		column="SUPER_ID"
		jdbc-type="BIGINT"
		access="anonymous"/>
		
	<reference-descriptor name="super"
		class-ref="BaseImpl">
			<foreignkey field-ref="superId" />
	</reference-descriptor>
</class-descriptor>

<class-descriptor
	class="BImpl"
	table="B">
	
	<field-descriptor
		name="id"
		column="ID"
		jdbc-type="BIGINT"
		primarykey="true"/>

	<field-descriptor
		name="superId"
		column="SUPER_ID"
		jdbc-type="BIGINT"
		access="anonymous"/>
		
	<reference-descriptor name="super"
		class-ref="BaseImpl">
			<foreignkey field-ref="superId" />
	</reference-descriptor>
</class-descriptor>

Right?

Now assume there exists only one BImpl instance and one AImpl instance. When
I execute the following code, I should get one instance of each. But
instead, I get four instances of BaseImpl.

PersistenceBroker pb = 
	PersistenceBrokerFactory.defaultPersistenceBroker();
QueryByCriteria q = 
	QueryFactory
		.newQuery(BaseInterface.class,
			     new Criteria(), 
			     true);
Collection r = pb.getCollectionByQuery(q);
for (Iterator i = r.iterator(); i.hasNext();) {
	System.err.println("class: " + i.next().getClass().getName());
}

Also, I've noticed that if I shuffle the order of extent-class elements in
the first class-descriptor, I get different results. Any suggestions?

Joshua Phillips
Contractor (SAIC)
Tel: 301 451 6346
Fax: 301 480 4222
phillijo@mail.nih.gov 


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org


Re: OJB extents, multiple joined tables

Posted by Thomas Dudziak <to...@first.fhg.de>.
Phillips, Joshua (NIH/NCI) wrote:

> When I query for all instances of class X, I expect to get all instances of
> class X and all instances of any subclass of X. But, in the following
> scenario, this isn't working.
> 
> Suppose the following:
>   - BaseImpl implements BaseInterface
>   - AInterface extends BaseInterface
>   - BInterface extends BaseInterface
>   - AImpl implements AInterface
>   - AImpl extends BaseImpl
>   - BImpl implements BInterface
>   - BImpl extends BaseImpl
> 
> Then the class-descriptor elements for this model should look like this:
> 
> <class-descriptor class="BaseInterface">
>    <extent-class class-ref="BaseImpl" />
>    <extent-class class-ref="AInterface" />
>    <extent-class class-ref="AImpl" />
>    <extent-class class-ref="BInterface" />
>    <extent-class class-ref="BImpl" />
> </class-descriptor>
> 
> <class-descriptor class="AInterface">
>    <extent-class class-ref="AImpl" />
> </class-descriptor>
> 
> <class-descriptor class="BInterface">
>    <extent-class class-ref="BImpl" />
> </class-descriptor>
> 
> <class-descriptor
> 	class="BaseImpl"
> 	table="BASE">
> 
>    <extent-class class-ref="AImpl" />
>    <extent-class class-ref="BImpl" />
> 	
> 	<field-descriptor
> 		name="id"
> 		column="ID"
> 		jdbc-type="BIGINT"
> 		primarykey="true"/>
> 		
> </class-descriptor>
> 
> <class-descriptor
> 	class="AImpl"
> 	table="A">
> 	
> 	<field-descriptor
> 		name="id"
> 		column="ID"
> 		jdbc-type="BIGINT"
> 		primarykey="true"/>
> 
> 	<field-descriptor
> 		name="superId"
> 		column="SUPER_ID"
> 		jdbc-type="BIGINT"
> 		access="anonymous"/>
> 		
> 	<reference-descriptor name="super"
> 		class-ref="BaseImpl">
> 			<foreignkey field-ref="superId" />
> 	</reference-descriptor>
> </class-descriptor>
> 
> <class-descriptor
> 	class="BImpl"
> 	table="B">
> 	
> 	<field-descriptor
> 		name="id"
> 		column="ID"
> 		jdbc-type="BIGINT"
> 		primarykey="true"/>
> 
> 	<field-descriptor
> 		name="superId"
> 		column="SUPER_ID"
> 		jdbc-type="BIGINT"
> 		access="anonymous"/>
> 		
> 	<reference-descriptor name="super"
> 		class-ref="BaseImpl">
> 			<foreignkey field-ref="superId" />
> 	</reference-descriptor>
> </class-descriptor>
> 
> Right?
> 
> Now assume there exists only one BImpl instance and one AImpl instance. When
> I execute the following code, I should get one instance of each. But
> instead, I get four instances of BaseImpl.
> 
> PersistenceBroker pb = 
> 	PersistenceBrokerFactory.defaultPersistenceBroker();
> QueryByCriteria q = 
> 	QueryFactory
> 		.newQuery(BaseInterface.class,
> 			     new Criteria(), 
> 			     true);
> Collection r = pb.getCollectionByQuery(q);
> for (Iterator i = r.iterator(); i.hasNext();) {
> 	System.err.println("class: " + i.next().getClass().getName());
> }
> 
> Also, I've noticed that if I shuffle the order of extent-class elements in
> the first class-descriptor, I get different results. Any suggestions?


When you map inheritance to multiple joined tables, you should not use 
extents for the classes that are connected via super-references, and you 
must ensure that the primary key is unique across the hierarchy.

Usually  you simply define the primary key field in the Java source in 
the top-level base class only (BaseImpl.java in your case), and all 
other subclasses use the very same primary key field as the foreignkey 
field of the super-reference:


<class-descriptor class="BaseInterface">
    <extent-class class-ref="BaseImpl" />
    <extent-class class-ref="AInterface" />
    <extent-class class-ref="BInterface" />
</class-descriptor>

<class-descriptor class="AInterface">
    <extent-class class-ref="AImpl" />
</class-descriptor>

<class-descriptor class="BInterface">
    <extent-class class-ref="BImpl" />
</class-descriptor>

<class-descriptor
	class="BaseImpl"
	table="BASE">

	<field-descriptor
		name="id"
		column="ID"
		jdbc-type="BIGINT"
		primarykey="true"/>
		
</class-descriptor>

<class-descriptor
	class="AImpl"
	table="A">
	
	<field-descriptor
		name="id"
		column="ID"
		jdbc-type="BIGINT"
		primarykey="true"/>
		
	<reference-descriptor name="super"
		class-ref="BaseImpl">
			<foreignkey field-ref="id" />
	</reference-descriptor>
</class-descriptor>

<class-descriptor
	class="BImpl"
	table="B">
	
	<field-descriptor
		name="id"
		column="ID"
		jdbc-type="BIGINT"
		primarykey="true"/>

	<reference-descriptor name="super"
		class-ref="BaseImpl">
			<foreignkey field-ref="id" />
	</reference-descriptor>
</class-descriptor>

Also, you should specify only the direct subclasses/-interfaces via 
extent-class tags (see BaseInterface above).

For details see here:

http://db.apache.org/ojb/docu/guides/advanced-technique.html#Mapping+Classes+on+Multiple+Joined+Tables

Tom

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org