While I can understand the desire for purity with that pattern, it
seems to me that it's too expensive to maintain in this use case.

I don't want to have to maintain a factory for building runtimes and
track all of the configuration needed to do that, just to turn off a
qualifier.    The existing runtime contains everything necessary --
there's just no easy way to get at it.

Maybe I am overlooking something.

I know you are busy, but can you provide an example of how I would
perform the same task for which I provided code (turn off a qualifier
in an otherwise duplicate ServerRuntime deep inside business logic)
using modules?

I was able to do this in six easily-understandable lines of code with
a ServerRuntime(Modules) constructor, and I fear that your suggested
approach requires me to create several separate classes, store
configuration globally, and create new modules for each qualifier that
I need to disable or change.

And John's use case is even more straight-forward than my own.


On Fri, Sep 27, 2013 at 12:49 PM, Andrus Adamchik
<[email protected]> wrote:
>> So it looks like I can reuse modules to create my own runtime.
>
> Yes.
>
>> However, the current 3.1 API isn't very friendly toward this approach.
>
>
> Yes - see my other email. A common pattern is to have some kind of external 
> factory that defines the modules.
>
> Also I don't perceive 'copy' method as very useful. The point of a second 
> runtime is that it is somehow different from the first, and modules is what 
> makes it different. I think you are doing it in a pre-3.1-DI-way - creating a 
> runtime first, then customizing it. I would usually place customization code 
> inside the modules, which are kind of deferred "closures".
>
> Andrus
>
>
> On Sep 27, 2013, at 7:39 PM, Mike Kienenberger <[email protected]> wrote:
>
>> So it looks like I can reuse modules to create my own runtime.
>> However, the current 3.1 API isn't very friendly toward this approach.
>> I had to clone the ServerRuntime class so that I could create my own
>> version so I could call CayenneRuntime(Module... modules) in my
>> constructor.
>>
>> Having a cloned ServerRuntime on which to make customizations seems
>> like a reasonable use case that we should support.   Can we add such a
>> method to ServerRuntime?   I think that's a better choice than making
>> it easier to create a ServerRuntime subclass.
>>
>> private ServerRuntime(Module... modules) {
>>    super(modules);
>> }
>>
>> public ServerRuntime copy() {
>>        return ServerRuntime(serverRuntime.getModules());
>> }
>>
>> It might be reasonable to make the private constructor public so that
>> someone can create ServerRuntimes where they are not required to pass
>> configurationLocation data but can provide their own alternative to
>> ServerModule.  This would have also worked in my case, removing the
>> need to have a copy() method.   However, I think the copy() method
>> provides assurance to the developer that this approach is viable.
>>
>>
>> Here's what my application code ended up looking like (using my cloned
>> class), and I think it's a good approach (except for the cloned class)
>> for these cases:
>>
>>        PaymentMethod paymentMethod = paymentHistory.getPaymentMethod();
>>        if (null == paymentMethod) {
>>            ServerRuntime currentRuntime = ServiceLocator.getCayenneRuntime();
>>
>>            // Payment method was invalidated at this point -- create
>> a runtime that can read invalidated payment methods
>>
>>            CopiedServerRuntime copiedRuntime = new
>> CopiedServerRuntime(currentRuntime);
>>            DataDomain dataDomain = copiedRuntime.getDataDomain();
>>            dataDomain.setSharedCacheEnabled(false);
>>
>>            EntityResolver entityResolver = dataDomain.getEntityResolver();
>>            ObjEntity paymentMethodObjEntity =
>> entityResolver.getObjEntity(PaymentMethod.class.getSimpleName());
>>            paymentMethodObjEntity.setDeclaredQualifier(null);
>>
>>            ObjectContext unrestrictedObjectContext =
>> copiedRuntime.getContext();
>>            PaymentHistory unrestrictedPaymentHistory =
>> unrestrictedObjectContext.localObject(paymentHistory);
>>            paymentMethod = unrestrictedPaymentHistory.getPaymentMethod();
>>        }
>>
>>
>> On Fri, Sep 27, 2013 at 11:46 AM, Mike Kienenberger <[email protected]> 
>> wrote:
>>> The idea of creating a new ServerRuntime is good, but the
>>> implementation leaves  me with a few questions.    My ServerRuntime is
>>> created in the context of the web app.
>>>
>>> Is it reasonable to try to create it using the information in the
>>> existing ServerRuntime?   Can I pull the injector and modules out of
>>> the existing Runtime and reuse them to create a new runtime, or do I
>>> need to create copies of the existing modules and injector?   My guess
>>> is that each runtime needs unique injector and modules objects, but I
>>> want to minimize the work I need to do.
>>>
>>> It looks like I have to pull my configurationLocation out of the
>>> ServerModule, which doesn't really provide it.
>>>
>>> I'm not seeing an easy way to create a new ServerRuntime from scratch
>>> without having access to data which was only available back when the
>>> web application started up, short of storing that information
>>> somewhere globally and reusing it.
>>>
>>> On Tue, Sep 24, 2013 at 2:04 PM, Andrus Adamchik <[email protected]> 
>>> wrote:
>>>>> The "special DataContext" case where the qualifier should be ignored can 
>>>>> probably be handled by starting a separate ServerRuntime, where you can 
>>>>> strip off the qualifiers. For whatever overhead it creates (ideally not 
>>>>> much), this has an advantage of cleanly separating "spaces" with 
>>>>> different ORM rules.
>>>>
>>>> Elaborating on this a bit… The old Configuration allowed multiple 
>>>> DataDomains, each of those requiring its own DataMap(s) saved in the 
>>>> project upfront. Good idea, but hard to use in practice.
>>>>
>>>> ServerRuntime (with single DD each) is more user-friendly. By starting 
>>>> multiple independent runtimes you to easily reuse a single mapping 
>>>> project, tweaking each in-memory copy local to each Runtime (as well as 
>>>> tweaking other parameters like cache). 2 Runtimes can reuse a single 
>>>> DataSource (JNDI, or otherwise), etc.
>>>>
>>>> Andrus
>>>>
>>
>

Reply via email to