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