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