It's entirely possible to do this, but in general I think it's a bad design *to* do 
it.  Collection descriptors are used to model relationships, not arbitrary dynamic 
queries.  The role of query customizers is to allow you to statically refine the 
relationship to make it more specific than just foreign-key/primary-key.  What you're 
attempting to do is to abuse the mechanism to make it a dynamic query mechanism which 
isn't the intention.  As a result I think you'll find a lot of subtle problems pop up 
if you go down this route, the first being caching (e.g. what happens when the parent 
item you're retrieving is answered from the cache and already has a collection that 
was customized dynamically from the last time it was used).  What I really think you 
want to do here is expose you're dynamic queries off of accessors you write yourself 
rather than trying to wedge them into collection descriptors.  Something like:

<class-descriptor class="Foo" table="Foo">
   <field-descriptor id="1"
      name="fooKey"
      column="foo_key"
      jdbc-type="INTEGER"
   />
</class-descriptor>

<class-descriptor class="Bar" table="Bar">
   <field-descriptor id="1"
      name="barKey"
      column="bar_key"
      jdbc-type="INTEGER"
      primarykey="true"
      autoincrement="false"
   />
   <field-descriptor id="2"
      name="fooKey"
      column="foo_key"
      jdbc-type="INTEGER"
      primarykey="true"
      autoincrement="false"
   />
</class-descriptor>

public class A
{
   private Integer fooKey;

   public Collection getBarsByKey(int barKey)
   {
      Criteria crit = new Criteria();
      crit.addEqualTo("fooKey", fooKey);
      crit.addEqualTo("barKey", barKey);

      Query q = QueryFactory.newQuery(Bar.class, crit);
      Collection results = broker.getCollectionByQuery(q);
   }
}

As an added bonus you don't have to play any tricks to get your dynamic information 
down to a query customizer, the dynamic information simply comes in as attributes on 
the method invocation.

If you insist on doing it the other way, the traditional way to pass arguments past an 
interface that doesn't support it is to use ThreadLocal but I really think you would 
be better served by reconsidering your design.

-----Original Message-----
From: Guido Beutler [mailto:[EMAIL PROTECTED]
Sent: Friday, December 19, 2003 10:01 AM
To: OJB Users List
Subject: Re: How to pass dynamic attribute values to QueryCustomizer
Implementations


Hello,

I'm a bit restricted in posting original code but I'll do my best :-)

Ok.



Brian McCallister wrote:

>Saw your original message and am thinking about this one. 
>
>Any chance you can post specifics? 
>
>Does value need to change while running, or is it just dependent upon
>something at load time?
>
>  
>
at runtime and that is the main problem. During load time I could solve 
by using the attributes at the repository.
I have two classes A and B and A has a 1:n relationshop to B.

<class-descriptor class="A" table="A">
   <field-descriptor id="1"
      name="a_key"
      column="a_key"
      jdbc-type="INTEGER"
   />
   <collection-descriptor name="b_col" element-class-ref="B" 
auto-retrieve="true" auto-update="false" auto-delete="false" 
proxy="false" refresh="false">
      <inverse-foreignkey field-id-ref="2"/>
      <query-customizer
      class="QueryCustomizerFilterImpl">
          <attribute
              attribute-name="attr1"
              attribute-value="value1"
          />
      </query-customizer>
   </collection-descriptor>
</class-descriptor>

<class-descriptor class="B" table="B">
   <field-descriptor id="1"
      name="b_key"
      column="b_key"
      jdbc-type="INTEGER"
      primarykey="true"
      autoincrement="false"
   />
   <field-descriptor id="2"
      name="a_key"
      column="a_key"
      jdbc-type="INTEGER"
      primarykey="true"
      autoincrement="false"
   />
</class-descriptor>



         Criteria crit = new Criteria();
         crit.addEqualTo("key", "value1");

         Criteria crit2 = new Criteria();
         crit2.addEqualTo("b_col.b_key", "pk_value_of_B");

        Criteria crit3 = new Criteria();
         crit3.addAndCriteria(crit);
         crit3.addAndCriteria(crit2);

         Query q = QueryFactory.newQuery(A.class, crit3);
         Collection results = broker.getCollectionByQuery(q);

I would like to get a collection a.b_col which contains only the 
elements of B which has the primary key "pk_value_of_B" not ALL
values. The query from above gives the correct instance of A but the 
collection is filled with all existing b which are very much.
So I build a QueryCustomizer where I can add the missing select criteria 
to the query which was build from OJB to load ALL b.

   public Query customizeQuery(Object anObject, PersistenceBroker 
aBroker, CollectionDescriptor aCod, QueryByCriteria aQuery)
   {
      aQuery.getCriteria().addEqualTo("b_key","pk_value_of_B");
       return aQuery;
   }

My problem is how to get the "pk_value_of_B" to the QueryCustomizer 
instance. The QueryCustomizer instance is constructed by OJB
so the default constructor is called, no way to pass a argument with my 
pk value. After that OJB calls the customizeQuery method and again
it looks like there is no way to get my key in there.

Hope this is more readable and a bit more detailed.

best regards,

Guido

>-Brian
>
>On Fri, 2003-12-19 at 10:09, Guido Beutler wrote:
>  
>
>>Hello,
>>
>>This is a repost with a better subject, hoping to get a hint.
>>
>>I build a custom QueryCustomizer implementation to restrict the 
>>retrieved values of a collection to a known primary key.
>>I saw that I could add attributes at the deployment descriptor but the 
>>value of the
>>primary key changes dynamically during my application.
>>
>>My sample:
>>
>>   public Query customizeQuery(Object anObject, PersistenceBroker 
>>aBroker, CollectionDescriptor aCod, QueryByCriteria aQuery)
>>   {
>>      aQuery.getCriteria().addEqualTo("field","value");
>>       return aQuery;
>>   }
>>
>>The "value" should change dynamically. Is there really no way to pass 
>>additional dynamic arguments to the implementation?
>>IA Simple workaround is to use System properties but of course this just 
>>a hack for a test case. It's not thread save, it's slow
>>etc.
>>I found no way to find out where the current query came from to build 
>>sonething like a callback. Extending the Query implementation by
>>a user object would be a solution buit this modification shouldn't be 
>>done without consulting the OJB crew.
>>Implementing a user object might be difficult because the querry which 
>>is passed to the QueryCustomizer  is generated by OJB and is
>>not directly coming from my code. So a modified Query would mean that 
>>the user object must be passed around by OJB Broker.
>>I still think that I miss something.
>>
>>best regards,
>>
>>Guido
>>
>>
>>---------------------------------------------------------------------
>>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]

Reply via email to