Re: How to pass dynamic attribute values to QueryCustomizer Implementations

2003-12-19 Thread Brian McCallister
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?

-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]



Re: How to pass dynamic attribute values to QueryCustomizer Implementations

2003-12-19 Thread Guido Beutler
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]
 




RE: How to pass dynamic attribute values to QueryCustomizer Implementations

2003-12-19 Thread Lance Eason
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

Re: How to pass dynamic attribute values to QueryCustomizer Implementations

2003-12-19 Thread Daniel Perry
I completely agree with it being bad design.  However, I am using OJB in
struts applications.  Lets take the example i gave before.  The struts
action would simply load a collection of managers from OJB, and put them
into the request scope.  The action would forward to a JSP.  The JSP would
itterate through the Managers, and the Employees within them, and print them
to the screen.  This is done using Tag libraries.

If the Managers datd only has Employees that match the (dynamicly generated)
query specifications, all the JSP has to do is itterate through the data.

If the Managers data has Employees that dont match the query specifications,
then the query has to be handled at the JSP level, which definitely is bad
design!  Also this creates a problem that web designers can cope with
taglibs, but cannot cope with writing scriptlets.

One solution is to create pageview that mimic data objects (and can even
reuse the same beans) but are copies of the contents.  Thus you copy the
managers details into a pageview object, and copy only the employees you
want into the pageview manager objects.  However this means more code.

Another downside of this solution is the performace loss of materialising
lots of objects that are unwanted.

Would the following query (slightly changed from your query) have any
implications on caching, etc? Would the cache not realise that criteria have
been used?

Criteria crit = new Criteria();
crit.addEqualTo(fooKey, fooKey);
crit.addEqualTo(bar.barKey, barKey);
Query q = QueryFactory.newQuery(Foo.class, crit);
Collection results = broker.getCollectionByQuery(q);


Daniel.

- Original Message - 
From: Lance Eason [EMAIL PROTECTED]
To: OJB Users List [EMAIL PROTECTED]
Sent: Friday, December 19, 2003 4:49 PM
Subject: RE: How to pass dynamic attribute values to QueryCustomizer
Implementations


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.


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: How to pass dynamic attribute values to QueryCustomizer Implementations

2003-12-19 Thread Guido Beutler
Hi,

Lance Eason wrote:

It's entirely possible to do this, but in general I think it's a bad design *to* do it.  

I never said that it is the best way 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.

 

You're right, that your solution would work. The other point of view ist 
that you have to write aditional code, the getBarsByKey method.
Of course this is more flexible than using a fixed class. Maybe 
dependent of the application which way is the better one.
I'll check what your solution would mean for my application.

Thanks, it's really another point of view.

best regards,

Guido



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: How to pass dynamic attribute values to QueryCustomizer Implementations

2003-12-19 Thread Daniel Perry
I think you are right.  I think there are two ways of looking at this.

1. From an OO programing point of view, OJB could be seen solely as a
persistance mechanism for objects. Queries should be used for realising a
collection of objects or a single object.  The single object (or each of the
collection of objects) should be complete trees (ie they should come back
from OJB as they went in).

2. From a Modeling point of view, OJB could be seen not only as a tool for
storing objects in a persistant manner, but also as a tool for working with
those objects.  One of the fundamental methods for working with data is
projection: specifying a tree to match, and finding matching occurances of
that tree.

This operation of projection is provided by SQL, but not in the same manner,
as all matching subtrees are returned (ie Managers are repeated on each row
of the results for their employees).  OJB put's it back together.

The kind of projection we are debating is provided with Conceptual Graphs
(peirce logic), and it works well.  However wether it should be applied to
OJB depends on which view you take (1 and 2 above).

Well, that's my thoughts! Feel free to disregard or discuss as you so feel
inclined!

Daniel.

- Original Message - 
From: Guido Beutler [EMAIL PROTECTED]

 Exactly and this is one reason why delegating the work to OJB for
 queries. This * must* not be bad design at all.
 It depends on the application I think.
 Another point is that I have a aditional hand written subselect which
 must be maintained and I can not see
 this problem by looking at the deployment descriptor. By using a
 queryCustomizer you can see at the
 descriptor that there is a dependency and where to make modifications if
 neccessary.

 best regards,

 Guido


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]