You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by Brian McCallister <mc...@forthillcompany.com> on 2004/03/12 16:58:04 UTC
Queries, Extents, and Joins (oh my!)
Given the interface Beer, two implementations of Beer (DomesticBeer and
ImportedBeer), and a class Truck (the generics stuff is compiled to
casts in 1.4, has no effect on mapping) which contains a collection of
Beer (classes and current metadata pasted at end of email) is there a
way to get the otm to fetch the whole shebang via a join on a query for
Truck?
public void testQueryCollections() throws Exception
{
OTMConnection conn = kit.acquireConnection(key);
Transaction tx = kit.getTransaction(conn);
tx.begin();
Truck truck = new Truck();
Beer schlitz = new DomesticBeer();
Beer cafs = new ImportedBeer();
Beer we_love_schlitz = new DomesticBeer("Sam Adams", 1.0);
truck.load(new Beer[]{schlitz, cafs, we_love_schlitz});
conn.makePersistent(truck);
tx.commit();
((BaseConnection)conn).getKernelBroker().clearCache();
tx = kit.getTransaction(conn);
tx.begin();
Query bq = QueryFactory.newQuery(Truck.class, new Criteria());
Collection all = conn.getCollectionByQuery(bq);
for (Iterator iterator = all.iterator(); iterator.hasNext();)
{
Object o = iterator.next();
System.err.println(o);
}
tx.commit();
conn.close();
}
Presently p6spy shows that it is using three selects to fetch
everything =/
-Brian
public interface Beer
{
String getBrand();
double getPrice();
}
public class DomesticBeer implements Beer
{
private Integer id;
private String brand;
private Double price;
public DomesticBeer()
{
this("Schlitz", 0.50);
}
public DomesticBeer(String brand, double price)
{
this.brand = brand;
this.price = new Double(price);
}
public String getBrand()
{
return brand;
}
public double getPrice()
{
return this.price.doubleValue();
}
}
public class ImportedBeer implements Beer
{
private Integer id;
private String brand;
private Double price;
private Double duty;
private String country;
/**
* Create a Caffrey's 70 at $2.50 and $0.20 import duty
*/
public ImportedBeer()
{
this("Caffrey's 70", "Scotland", 2.50, .20);
}
public ImportedBeer(String brand, String country, double price,
double import_duty)
{
this.brand = brand;
this.country = country;
this.price = new Double(price);
this.duty = new Double(import_duty);
}
public String getBrand()
{
return brand;
}
public String getCountry()
{
return this.country;
}
public double getPrice()
{
return this.price.doubleValue() + this.duty.doubleValue();
}
}
import java.util.HashSet;
import java.util.Set;
public class Truck<Cargo>
{
/** Unique identifier for truck */
private Integer id;
/** What the truck is carrying */
private Set<Cargo> cargo = new HashSet<Cargo>();
/**
* Load a single item of cargo
*/
public void load(Cargo item)
{
this.cargo.add(item);
}
/**
* Load a bunch of cargo
*/
public void load(Cargo[] items)
{
for (int i = 0; i < items.length; i++)
{
this.load(items[i]);
}
}
/**
* Remove all cargo and return the contents
*/
public Set<Cargo> unload()
{
HashSet<Cargo> set = null;
synchronized (cargo)
{
set = new HashSet<Cargo>(this.cargo);
this.cargo.clear();
}
return set;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE descriptor-repository PUBLIC
"-//Apache Software Foundation//DTD OJB Repository//EN"
"repository.dtd"
[
<!ENTITY database SYSTEM "repository_database.xml">
<!ENTITY internal SYSTEM "repository_internal.xml">
]>
<descriptor-repository version="1.0" isolation-level="read-uncommitted"
proxy-prefetching-limit="50">
&database;
&internal;
<class-descriptor
class="Truck"
table="TRUCKS"
>
<field-descriptor
name="id"
column="ID"
jdbc-type="INTEGER"
primarykey="true"
autoincrement="true"
/>
<collection-descriptor
name="cargo"
element-class-ref="Beer"
otm-dependent="true"
auto-retrieve="true"
collection-
class="org.apache.ojb.broker.util.collections.ManageableHashSet">
<inverse-foreignkey field-ref="TRUCK_ID"/>
</collection-descriptor>
</class-descriptor>
<class-descriptor
class="Pub"
table="PUBS"
>
<field-descriptor
name="id"
column="ID"
jdbc-type="INTEGER"
primarykey="true"
autoincrement="true"
/>
<field-descriptor
name="name"
column="NAME"
jdbc-type="VARCHAR"
length="50"
/>
<field-descriptor
name="debt"
column="DEBT"
jdbc-type="DOUBLE"
/>
</class-descriptor>
<class-descriptor class="Beer">
<extent-class class-ref="DomesticBeer"/>
<extent-class class-ref="ImportedBeer"/>
</class-descriptor>
<class-descriptor
class="DomesticBeer"
table="DOMESTIC_BEER"
>
<field-descriptor
name="id"
column="ID"
jdbc-type="INTEGER"
primarykey="true"
autoincrement="true"
/>
<field-descriptor
name="TRUCK_ID"
column="TRUCK_ID"
jdbc-type="INTEGER"
access="anonymous"
/>
<field-descriptor
name="brand"
column="BRAND"
jdbc-type="VARCHAR"
length="50"
/>
<field-descriptor
name="price"
column="PRICE"
jdbc-type="DOUBLE"
/>
</class-descriptor>
<class-descriptor
class="ImportedBeer"
table="IMPORTED_BEER"
>
<field-descriptor
name="id"
column="ID"
jdbc-type="INTEGER"
primarykey="true"
autoincrement="true"
/>
<field-descriptor
name="TRUCK_ID"
column="TRUCK_ID"
jdbc-type="INTEGER"
access="anonymous"
/>
<field-descriptor
name="brand"
column="BRAND"
jdbc-type="VARCHAR"
length="50"
/>
<field-descriptor
name="country"
column="COUNTRY"
jdbc-type="VARCHAR"
length="50"
/>
<field-descriptor
name="price"
column="PRICE"
jdbc-type="DOUBLE"
/>
<field-descriptor
name="duty"
column="IMPORT_DUTY"
jdbc-type="DOUBLE"
/>
</class-descriptor>
</descriptor-repository>
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org
Re: Queries, Extents, and Joins (oh my!)
Posted by Jakob Braeuchi <jb...@gmx.ch>.
hi brian,
Brian McCallister wrote:
> Given the interface Beer, two implementations of Beer (DomesticBeer and
> ImportedBeer), and a class Truck (the generics stuff is compiled to
> casts in 1.4, has no effect on mapping) which contains a collection of
> Beer (classes and current metadata pasted at end of email) is there a
> way to get the otm to fetch the whole shebang via a join on a query for
> Truck?
you have 3 concrete classes truck, domestic beer and imported beer. ojb loads
every concrete class in it's own query that's why you see 3 queries. actually
prefetching is also involved here, otherwise you'll see a beer-query for each
instance of truck ;)
jakob
>
>
> public void testQueryCollections() throws Exception
> {
> OTMConnection conn = kit.acquireConnection(key);
> Transaction tx = kit.getTransaction(conn);
>
> tx.begin();
> Truck truck = new Truck();
> Beer schlitz = new DomesticBeer();
> Beer cafs = new ImportedBeer();
> Beer we_love_schlitz = new DomesticBeer("Sam Adams", 1.0);
> truck.load(new Beer[]{schlitz, cafs, we_love_schlitz});
> conn.makePersistent(truck);
> tx.commit();
>
> ((BaseConnection)conn).getKernelBroker().clearCache();
>
> tx = kit.getTransaction(conn);
> tx.begin();
> Query bq = QueryFactory.newQuery(Truck.class, new Criteria());
> Collection all = conn.getCollectionByQuery(bq);
> for (Iterator iterator = all.iterator(); iterator.hasNext();)
> {
> Object o = iterator.next();
> System.err.println(o);
> }
> tx.commit();
> conn.close();
> }
>
> Presently p6spy shows that it is using three selects to fetch
> everything =/
>
> -Brian
>
> public interface Beer
> {
> String getBrand();
> double getPrice();
> }
>
>
> public class DomesticBeer implements Beer
> {
> private Integer id;
> private String brand;
> private Double price;
>
> public DomesticBeer()
> {
> this("Schlitz", 0.50);
> }
>
> public DomesticBeer(String brand, double price)
> {
> this.brand = brand;
> this.price = new Double(price);
> }
>
> public String getBrand()
> {
> return brand;
> }
>
> public double getPrice()
> {
> return this.price.doubleValue();
> }
> }
>
>
> public class ImportedBeer implements Beer
> {
> private Integer id;
> private String brand;
> private Double price;
> private Double duty;
> private String country;
>
> /**
> * Create a Caffrey's 70 at $2.50 and $0.20 import duty
> */
> public ImportedBeer()
> {
> this("Caffrey's 70", "Scotland", 2.50, .20);
> }
>
> public ImportedBeer(String brand, String country, double price,
> double import_duty)
> {
> this.brand = brand;
> this.country = country;
> this.price = new Double(price);
> this.duty = new Double(import_duty);
> }
>
> public String getBrand()
> {
> return brand;
> }
>
> public String getCountry()
> {
> return this.country;
> }
>
> public double getPrice()
> {
> return this.price.doubleValue() + this.duty.doubleValue();
> }
> }
>
>
> import java.util.HashSet;
> import java.util.Set;
>
> public class Truck<Cargo>
> {
> /** Unique identifier for truck */
> private Integer id;
>
> /** What the truck is carrying */
> private Set<Cargo> cargo = new HashSet<Cargo>();
>
> /**
> * Load a single item of cargo
> */
> public void load(Cargo item)
> {
> this.cargo.add(item);
> }
>
> /**
> * Load a bunch of cargo
> */
> public void load(Cargo[] items)
> {
> for (int i = 0; i < items.length; i++)
> {
> this.load(items[i]);
> }
> }
>
> /**
> * Remove all cargo and return the contents
> */
> public Set<Cargo> unload()
> {
> HashSet<Cargo> set = null;
> synchronized (cargo)
> {
> set = new HashSet<Cargo>(this.cargo);
> this.cargo.clear();
> }
> return set;
> }
> }
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <!DOCTYPE descriptor-repository PUBLIC
> "-//Apache Software Foundation//DTD OJB Repository//EN"
> "repository.dtd"
> [
>
> <!ENTITY database SYSTEM "repository_database.xml">
> <!ENTITY internal SYSTEM "repository_internal.xml">
>
> ]>
>
> <descriptor-repository version="1.0" isolation-level="read-uncommitted"
> proxy-prefetching-limit="50">
>
> &database;
> &internal;
>
> <class-descriptor
> class="Truck"
> table="TRUCKS"
> >
> <field-descriptor
> name="id"
> column="ID"
> jdbc-type="INTEGER"
> primarykey="true"
> autoincrement="true"
> />
> <collection-descriptor
> name="cargo"
> element-class-ref="Beer"
> otm-dependent="true"
> auto-retrieve="true"
> collection-
> class="org.apache.ojb.broker.util.collections.ManageableHashSet">
> <inverse-foreignkey field-ref="TRUCK_ID"/>
> </collection-descriptor>
> </class-descriptor>
>
> <class-descriptor
> class="Pub"
> table="PUBS"
> >
> <field-descriptor
> name="id"
> column="ID"
> jdbc-type="INTEGER"
> primarykey="true"
> autoincrement="true"
> />
> <field-descriptor
> name="name"
> column="NAME"
> jdbc-type="VARCHAR"
> length="50"
> />
> <field-descriptor
> name="debt"
> column="DEBT"
> jdbc-type="DOUBLE"
> />
> </class-descriptor>
>
> <class-descriptor class="Beer">
> <extent-class class-ref="DomesticBeer"/>
> <extent-class class-ref="ImportedBeer"/>
> </class-descriptor>
>
> <class-descriptor
> class="DomesticBeer"
> table="DOMESTIC_BEER"
> >
> <field-descriptor
> name="id"
> column="ID"
> jdbc-type="INTEGER"
> primarykey="true"
> autoincrement="true"
> />
> <field-descriptor
> name="TRUCK_ID"
> column="TRUCK_ID"
> jdbc-type="INTEGER"
> access="anonymous"
> />
> <field-descriptor
> name="brand"
> column="BRAND"
> jdbc-type="VARCHAR"
> length="50"
> />
> <field-descriptor
> name="price"
> column="PRICE"
> jdbc-type="DOUBLE"
> />
> </class-descriptor>
>
> <class-descriptor
> class="ImportedBeer"
> table="IMPORTED_BEER"
> >
> <field-descriptor
> name="id"
> column="ID"
> jdbc-type="INTEGER"
> primarykey="true"
> autoincrement="true"
> />
> <field-descriptor
> name="TRUCK_ID"
> column="TRUCK_ID"
> jdbc-type="INTEGER"
> access="anonymous"
> />
> <field-descriptor
> name="brand"
> column="BRAND"
> jdbc-type="VARCHAR"
> length="50"
> />
> <field-descriptor
> name="country"
> column="COUNTRY"
> jdbc-type="VARCHAR"
> length="50"
> />
> <field-descriptor
> name="price"
> column="PRICE"
> jdbc-type="DOUBLE"
> />
> <field-descriptor
> name="duty"
> column="IMPORT_DUTY"
> jdbc-type="DOUBLE"
> />
> </class-descriptor>
> </descriptor-repository>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org