i just added some fixes to support customizable 1:n queries.
just add a query-customizer class to the collection-descriptor.
this class must implement the QueryCustomizer interface, a QueryCustomizerDefaultImpl is alreay there as a base class.
...
<query-customizer
class="org.apache.ojb.broker.accesslayer.QueryCustomizerDefaultImpl">
<attribute
attribute-name="attr1"
attribute-value="value1"
/>
...
the interface defines the single method below which is used to customize (or completely rebuild) the query passed as argument. the interpretation of attribute-name ans attribute-value is up to your class !
/**
* Return a new Query based on the original Query, the originator object and
* the additional Attributes
*
* @param anObject the originator object
* @param aBroker the PersistenceBroker
* @param aCod the CollectionDescriptor
* @param aQuery the original 1:n-Query
* @return Query the customized 1:n-Query
*/
public Query customizeQuery(Object anObject, PersistenceBroker aBroker, CollectionDescriptor aCod, Query aQuery);
hth jakob
sclark wrote:
Jakob,
You are correct; all of the logic is in the Builder class. As you say, there are lots of possibilities for these constraints. I think that the best way to express them is to use Java, rather than trying to invent some new syntax that fits inside of XML. And I bet that a fairly small set of stock builders, appropriately parameterized, would hit the vast majority of cases.
Hmmm ... I bet it would be quite easy to write an OqlQueryBuilder which would take a single parameter, an OQL string, and parse it. Imagine this:
<class-descriptor class="Employee" ...
<collection-descriptor
name="recentOutsideProjects"
elementClass="Project"
... >
<inverse-foreignkey field-ref="employeeId" />
<query class="OqlQueryBuilder">
<attribute attribute-name="queryString"
attribute-value="project.startDate.year > 2000 and project.org <> emp.org"
/>
</query>
</collection-descriptor>
Heck, maybe we could even write:
<collection-descriptor name="recentOutsideProjects" elementClass="Project" ... > <inverse-foreignkey field-ref="employeeId" /> <query language="oql" queryString="project.startDate.year > 2000 and project.org <> emp.org" /> </collection-descriptor>
One of the reasons that I prefer a Builder to a Refiner is that I have relationships which don't involve FK's at all, so I'd like a way to
express those and never get any of the default Criteria in there. But
maybe it's sufficient to use a refinement approach, and make the FX spec
optional in repository.xml if there's a query. That way if I have FK's,
I can refine; if there aren't FK's, then I can just start from scratch.
-steve
From: Jakob Braeuchi <[EMAIL PROTECTED]>cds);
hi steve,
what i miss in this approach is the operation (=, <>, like, between etc.) .
as far as i understand your proposal, the operation and the whole logic is dependent of the query-builder. this makes it quite easy for us to implement it in ojb, but it moves the burden of implementation to the user. especially when you think of accessing the 'originator' object as bill pointed out.
as there are lots of possibilities for query-constraints, i'm not sure whether we'll be able to provide the most useful ones (from a user's point of view). on the other hand your approach provides all the flexibility one might need...
imo we should just provide a standard query-restrictor using static parameters and operations for those who need simple restrictions only.
just my 0.02 chf
jakob
sclark wrote:
Here's an idea on the collection restriction discussion. How about something like this:
/**
* Interface implemented by classes which are used to create a custom
* query for the contents of a collection property, when the usual
* fk/pk approach is insufficient.
*/
interface org.apache.ojb.broker.query.QueryBuilder /** Build the query to retrieve the specified collection property */
Query buildQuery(Object obj, ClassDescriptor cld, CollectionDescriptor
}
class PersistenceBrokerImpl { private void retrieveCollection(...) { if (cds.getQueryBuilder() != null) { fkQuery = cds.getQueryBuilder.buildQuery(obj, cld, cls); } else if (cds.isMtoNRelation()) { fkQuery = getMtoNQuery(obj, cld, cds); } else { fkQuery = getForeignKeyQuery(obj, cld, cds); } } }
Then in my app I would write something like this:
class gov.doi.cap.ojb.query.BuildProjectsQuery implements QueryBuilder { ... }
<collection-descriptor
name="projects"
elementClass="gov.doi.cap.ojb.dataobjects.Project"
... >
<query class="gov.doi.cap.ojb.query.BuildProjectsQuery">
<attribute attribute-name="earliestStart"
attribute-value="1999"
/>
<attribute attribute-name="latestStart"
attribute-value="2001"
/>
</query>
</collection-descriptor>
This would allow great flexibility in the specification of the collection contents, without requiring a query syntax to be defined in XML.
-steve
Steve Clark Technology Applications Team Natural Resources Research Center/USGS [EMAIL PROTECTED] (970)226-9291
Date: Fri, 21 Feb 2003 17:49:32 +0100 From: Jakob Braeuchi <[EMAIL PROTECTED]> To: OJB Users List <[EMAIL PROTECTED]> Subject: Re: 1:M querys constraints
hi bill,
what kind of restrictions woukd you need in the collection-descriptor ? do we need the full blown criteria there ? have you already any ideas about the definition of these restrictions ?
i'm asking these questions because i do not want to parse restrictions in the collection-descriptor.
i prefer a simpler solution like :
<restriction field="firstname" operation="=" value="Mark" /> <restriction field="lastname" operation="like" value="M%" />
how could we handle 'AND' / 'OR' ?
what do yout think about ?
jakob
--------------------------------------------------------------------- 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]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]