Heh :-) 

In 3.1 we have a nice mechanism for creating simple extension points of 
Cayenne. I hope we'll start using that more to unwind these chains and allow 
for easier extensibility. I guess community input and contributions should 
become a driving force here.

Andrus


On Jun 30, 2011, at 4:09 PM, Wernke zur Borg wrote:
> Thanks Andrus, that got me going. I had to create six classes to add a
> single word to a query! ;)
> 
> And fortunately that single word is the first one to be output, so in my
> appendJoinSubtree() function I am simply outputting " INNER" and then
> call super.appendJoinSubtree() for the rest. Would have been more
> tedious if I had to insert something in the middle, because then I would
> have had to copy the whole method plus two private data members and an
> inner class.
> 
> Anyway, it is working now, thanks again.
> 
> Wernke
> 
> 
> 
> Am 29.06.2011 10:03, schrieb Andrus Adamchik:
>> There's a tree of related objects involved. Check Oracle8Adapter and related 
>> classes. It actually switches Cayenne back to joins in WHERE clause. The 
>> chain of overridden objects goes like this:
>> 
>> Oracle8Adapter.getAction(..) 
>>  Oracle8ActionBuilder
>>     Oracle8SelectAction
>>       Oracle8JoinStack
>> 
>> 
>> Oracle8JoinStack is where the magic happens. BTW, you can create a simpler 
>> subclass of JoinStack, just overriding 'appendJoinSubtree' to change " JOIN" 
>> to " INNER JOIN".
>> 
>> Andrus
>> 
>> 
>> 
>> On Jun 28, 2011, at 10:52 AM, Wernke zur Borg wrote:
>> 
>>> Thanks for your answers. I would like to stick to version 3.1, so could
>>> somebody give me a hint as to where to modify the JOIN syntax in a
>>> custom DB adapter? I looked at all the existing DB adapters and I guess
>>> I would subclass JdbcAdapter but I could not find a suitable method to
>>> override.
>>> 
>>> Thanks, Wernke
>>> 
>>> 
>>> Am 21.06.2011 15:41, schrieb Andrus Adamchik:
>>>> Past versions of Cayenne used joins in WHERE clause, that were likely 
>>>> compatible with MS Access. So older Cayenne 2.0.x should probably work. 
>>>> 
>>>> Also writing a custom Access DbAdapter that adds INNER should be possible. 
>>>> 
>>>> Andrus
>>>> 
>>>> On Jun 21, 2011, at 11:36 AM, Aristedes Maniatis wrote:
>>>>> On 21/06/11 6:02 PM, Wernke zur Borg wrote:
>>>>>> Hi,
>>>>>> 
>>>>>> I am having a few problems with queries on an MS Access database when I
>>>>>> use object relationships to access related tables. I am using Cayenne
>>>>>> 3.1 M2.
>>>>>> 
>>>>>> My case is very simple. Let's say I have two tables A and B where A has
>>>>>> a column col containing a primary key of B. Given an object a from table
>>>>>> A with colValue, I want to access the related record of B using a.getB().
>>>>>> 
>>>>>> Cayenne creates a select query that joins A and B like this:
>>>>>> 
>>>>>> SELECT DISTINCT t0.columns... FROM B t0 *JOIN* A t1 ON (t0.pk = t1.col)
>>>>>> WHERE t1.pk = ? [bind: 1->  a.pkValue]
>>>>>> 
>>>>>> The first thing is that this produces a syntax error as the simple *JOIN
>>>>>> *keyword is not valid in MS Access. They want an explicit *INNER JOIN*.
>>>>> I've never heard of anyone using MS Access before as an SQL engine, so 
>>>>> this might be one reason why. I would run, not walk, to another db if you 
>>>>> can at all manage that within your environment.
>>>>> 
>>>>> 
>>>>>> But secondly I wonder why Cayenne needs a JOIN in this case anyway,
>>>>>> since it is of no use at all. Why does it not use something like:
>>>>>> 
>>>>>> SELECT t0.columns... FROM B t0 WHERE t0.pk = ? [bind 1->  a.colValue]
>>>>>> 
>>>>> I guess since any SQL engine will optimise that out, the fact that 
>>>>> Cayenne does it in the most generic way usually doesn't matter. I haven't 
>>>>> seen the code in question specifically, but Cayenne performs JOINs very 
>>>>> often and has a bunch of code which knows how to do that (multiple keys, 
>>>>> qualifiers, inheritance, etc) and that code is just being reused here.
>>>>> 
>>>>> 
>>>>>> My workaround is to manually create a SELECT query to access B without
>>>>>> joining it A:
>>>>>> 
>>>>>> Expression e = ExpressionFactory.matchExp(B.primaryKeyProperty, 
>>>>>> A.colValue);
>>>>>> SelectQuery q = new SelectQuery(B.class, e);
>>>>>> 
>>>>>> This works but of course it would be nicer to use the getter function
>>>>>> A.getB().
>>>>>> 
>>>>>> Is there a possibility to either avoid the JOIN or tell Cayenne to use
>>>>>> INNER JOIN instead of JOIN ?
>>>>> Yes, you can write specific db adapters for databases of your choice. 
>>>>> You'll need to get your hands into Cayenne itself, but the classes in 
>>>>> question aren't too hard to understand. Let us know if you need more 
>>>>> pointers to do that. I am guessing that none of the development team will 
>>>>> be easily able to test against Access, and we don't currently run any 
>>>>> unit tests against Access. But if you can help make it work, then so much 
>>>>> the better.
>>>>> 
>>>>> Cheers
>>>>> Ari
>>>>> 
>>>>> -- 
>>>>> -------------------------->
>>>>> Aristedes Maniatis
>>>>> GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A
>>>>> 
>>> 
> 
> 

Reply via email to