On May 11, 2005, at 11:10 AM, Cris Daniluk wrote:
> On 5/11/05, Erik Hatcher <eri..hatchersolutions.com> wrote:
>
>> I want to generate something like this in each of my superclasses:
>>
>> static public final User forPK(Object pk) {
>> return (User) DataObjectUtils.objectForPK(getCurrentDataContext
>> (), User.class, pk);
>> }
>>
>> First of all, is this approach reasonable to do? Are others doing
>> something similar? getCurrentDataContext() comes from my custom base
>> class and pulls the DataContext from thread local storage. My goal
>> is to keep direct Cayenne dependence out of my Tapestry code, and for
>> things like looking up an object by its primary key, I'd like to that
>> to be clean and straightforward to use. My reliance on Cayenne will
>> ideally be indirect as in the above finder method.
>>
>>
> Nothing wrong with this approach, except that because its generic, it
> may lead to unclear usage. For example, if you have a compound key,
> you're going to need to pass a map, but this signature will happily
> accept an object, which will never find a match, but never throw an
> error indicating as much.
The Object will come from DataObjectUtils.pkForObject(), so it'll be
in a Cayenne-friendly format already. Maybe I should be
using .compoundPKForObject instead? I do have some tables with
compound primary keys, but have not used them with this approach yet.
> This is a problem with DataObjectUtils no matter what, of course, but
> with a wrapper like this, the developer is less aware of what's
> happening under the hood. I think you can work around this by having a
> branch depending on if classGen.Entity.DbEntity.PrimaryKey has more
> than 1 entry or not (if more than 1, force a Map). If your people are
> smart, though, it doesn't really matter.
It's a one-man "team" for this project, so my "people" are definitely
not smart enough so I'm trying to make life simpler and cleaner for
"them" overall :))
>> Second - how can I get the package name of User when generating
>> _User? I have superclasses generated into a separate package than
>> the subclass objects (which I create manually).
>>
>>
>
> Good question :) I've done similar things before, but always by hand
> in the wrapper class, rather than in the generator as you're trying to
> do. If you look at superclass.vm and subclass.vm, they both reference
> their (different) package the same way: classGen.packageName. I have a
> hunch that you don't have access to this information, but if you want
> to be sure, check the ClassGenerator class. This is what Cayenne
> passes to velocity as 'classGen'. It might be accessible through
> classGen.entity (ObjEntity)
Based on your feedback, it seems that doing this generically is not
the wisest choice, but rather to hand-code in my model subclasses a
finder by PK.
I had been spelunking in ClassGenerator, but not deeper into the
classGen object graph, before sending the original message. I'll
look deeper if the generator approach is what I want to run with.
Thanks,
Erik
This archive was generated by hypermail 2.0.0 : Wed May 11 2005 - 13:18:32 EDT