I've had to make a copy of a ServerRuntime object before too - an API for it would be useful.
On Fri, Sep 27, 2013 at 11:39 AM, 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 > >> >
