tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tom van Dijk <...@tvandijk.nl>
Subject Re: Using multiple databases?
Date Mon, 18 Oct 2010 20:05:59 GMT
I've made a report in JIRA, TAP5-1313. 

You may expect it to be a new functionality issue for allowing extra
ModuleDef objects to be added, but the result is quite different, because I
believe dynamic services really should be in the same module that wants to
define them. Anyway, you can find it in JIRA.


On Sun, 17 Oct 2010 09:47:19 -0700, Howard Lewis Ship <hlship@gmail.com>
> Patches needs to come through the JIRA system, for administrative
> On Sun, Oct 17, 2010 at 7:11 AM, Tom van Dijk <tom@tvandijk.nl> wrote:
>> Okay, I got to work a bit and here's a patch that does what I
>> Uhm, I'm not sure if I'm supposed to submit patches this way.
>> Anyway, it allows extra ModuleDef objects to be added.
>> The patch shows the general idea, I'm pretty sure I'm missing something
>> that breaks everything (although it builds fine) and I suppose I'm not
>> really following coding/commenting conventions.
>> Unfortunately, tapestry-spring can't be modified to use this technique,
>> since it relies on a ServerContext object which is unreachable because
>> ApplicationGlobals doesn't have it before performRegistryStartup.
>> Tom.
>> On Sat, 16 Oct 2010 23:51:04 +0200, Tom van Dijk <tom@tvandijk.nl>
>>> I'm sorry, but I don't "get" it.
>>> Where can I find this service builder factory service? I use
>>> 5.2.2-SNAPSHOT from your git.
>>> The basic idea I'm now trying to work upon is that through some kind
>>> configuration, the MultiHibernateModule class can figure out which
>>> databases are used. Ideally I want it to be possible to access two
>>> databases that have the same model (e.g. two book libraries). I don't
>> want
>>> to have to specify services in the web application or in model
>> but
>>> I would like the MultiHibernateModule to take care of creating the
>>> appropriate Session«name», HibernateSessionManager«name» and similar
>>> services.
>>> What tapestry-spring does is override TapestryFilter, requiring
>> developers
>>> to modify web.xml; besides, it doesn't scale as I don't see how
>>> tapestry modules can override TapestryFilter to add their "dynamic"
>>> services.
>>> As said, I can't find a service builder factory service. Where can I
>> find
>>> it? I can imagine contributing a service or configuration to a
>> tapestry-ioc
>>> service that adds 'dynamic' services [*] without "hacks" like a custom
>>> TapestryFilter. [*] 'dynamic' defined as "determined when starting the
>>> registry". Non-dynamic (call it static, whatever) could be defined as
>>> compile-time / binary defined. There is no way for the
>> MultiHibernateModule
>>> to know which services it should define before the application is
>>> initialized.
>>> I can imagine such a dynamic service builder work as follows. After
>>> "normal" service definitions have been collected, all contributions
>>> (OrderedConfiguration) to the dynamic service builder are collected as
>> well
>>> and processed, resulting in possible extra services. I think this
>> concept
>>> would make tapestry-spring cleaner as well.
>>> So, I'm again at your mercy, sir! Unless I'm overlooking something, my
>>> "humble request" would need something new in tapestry-ioc.
>>> On Sat, 16 Oct 2010 10:52:15 -0700, Howard Lewis Ship
>>> wrote:
>>>> I think you are on the right track, but I think you'll find it easier
>>>> to go with the flow of Tapestry using a marker annotation for each
>>>> database, rather than a single annotation that names the database.
>>>> Either way, the idea that you inject the Session you need is at the
>>> core.
>>>> You'll also want to tweak @CommitAfter to search for an annotation to
>>>> determine *which* Session's transaction to commit.
>>>> You may also want to consider a service builder factory service to
>>>> make it easy to define new Hibernate services, since there's a lot in
>>>> parallel.
>>>> The new @Contribute annotation will make it easier to contribute
>>>> configuration to a specific Hibernate connection factory, or to any
>>>> them (via marker annotations).
>>>> On Sat, Oct 16, 2010 at 7:56 AM, Tom van Dijk <tom@tvandijk.nl>
>>>>>  After a "slight" delay, I've been working on a solution. (I'm a
>>>>> Master's
>>>>> student and it appears I have little spare time for private projects
>>>>> right
>>>>> now, hence the delay)
>>>>> I didn't want to use Spring if it's not needed; in my opinion just
>>> using
>>>>> Tapestry should be enough.
>>>>> One line of thought that I've been toying with the last couple of
>>>>> is to
>>>>> have a @UseDatabase annotation, e.g.
>>>>> @Inject @UseDatabase("one") Session sessionOne,
>>>>> @Inject @UseDatabase("two") Session sessionTwo
>>>>> The implementation is a custom object provider, which provides
>>>>> for
>>>>> the interfaces Session, HibernateSessionSource,
>>> HibernateSessionManager,
>>>>> HibernateTransactionDecorator and HibernateTransactionAdvisor.
>>>>> There is a configurator object (MultiHibernateEntityPackageManager)
>>> that
>>>>> is
>>>>> configured by Map<String, Collection<String>>, with the semantics
>>>>> (database-id) -> {packageName}
>>>>> By default is uses "/hibernate-«name».cfg.xml" for the
>>>>> Obviously, because it's a custom object provider, the whole
>>>>> stuff
>>>>> doesn't apply, which is a terribly ugly hack really. Besides, it's
>>>>> absolutely not compatible with the original tapestry-hibernate-core
>>>>> module.
>>>>> A different issue is that the Tapestry/Hibernate (web) integration
>>> module
>>>>> also depends on Session objects, which needs to be solved at some
>> point
>>>>> (right now I just deleted them, keeping only a modified
>>>>> CommitAfterWorker,
>>>>> which works btw).
>>>>> All in all, this seems to work, but it's ugly and I have some
>>> I'm
>>>>> also violating Tapestry principles somewhere.
>>>>> A different line of thought that I am considering is using a
>>>>> like
>>>>> in the Tapestry / Swing integration package, to create all services.
>>>>> There
>>>>> is still the issue of the Tapestry/Hibernate (web) integration
>>>>> assuming that there is only one database.
>>>>> It would have
>>>>> @InjectService("SessionOne") Session sessionOne.
>>>>> I don't really see how the Marker option would be implemented, but
>> this
>>>>> may
>>>>> be my lack of experience with Tapestry. You say it can be done
>>>>> changing the framework? At the very least, it seems Persisting /
>>>>> ValueEncoder / all that stuff would be broken.
>>>>> Any thoughts?
>>>>> Op 2-6-2010 17:23, Howard Lewis Ship schreef:
>>>>>> there's been some talk about allowing for seperate Sessions (and
>>>>>> related), using marker annotation to identify which one you need.
>>>>>> I.e., you might have
>>>>>> @Inject @Product
>>>>>> private Session productSession;
>>>>>> @Inject @Content
>>>>>> private Session contentSession;
>>>>>> That's not too hard; the tricky part is the replication of several
>>>>>> services with the same interface; i.e., you will need an @Product
>>>>>> HibernateConfigurer and a @Content HibernateConfigurer, etc.
>>>>>> This could all be done, and done on top of tapestry-hibernate
>>>>>> changing the framework, I think.  The only tricky part is that the
>>>>>> default HibernateConfigurer assumes that you start by reading
>>>>>> hibernate.cfg.xml and that would need to be more flexible
>>>>>> (hibernate-products.cfg.xml, hibernate-session.cfg.xml).
>>>>>> On Tue, Jun 1, 2010 at 3:25 PM, Tom van Dijk<tom@tvandijk.nl>
>>>>>>  wrote:
>>>>>>> Hi,
>>>>>>> I'll be brief to save you time.
>>>>>>> I want to turn my webapplication (for a company I work for, I'm
>> doing
>>> a
>>>>>>> proof of concept to see if what I want is possible) into a
>>>>>>> based
>>>>>>> system.
>>>>>>> Our web applications use multiple databases (to enforce seperation
>> of
>>>>>>> concerns and for possible future scaling)
>>>>>>> We currently use two filters that provide two EntityManagerFactory
>>>>>>> objects
>>>>>>> (this is just for a small proof of concept webapp) and what I
>>>>>>> like
>>>>>>> is
>>>>>>> to have two differently configured Session services. Obviously,
>>> want
>>>>>>> to
>>>>>>> move on, embrace the future and start using a proper IoC
>>>>>>> Now I see in the issue system that this (using multiple databases)
>> is
>>>>>>> unsupported. My question concerns a generalized approach. My
>>>>>>> thoughts
>>>>>>> were on creating some kind of a general Factory service that
>>>>>>> spawn
>>>>>>> the
>>>>>>> necessary custom services, but at second thought I found something
>>> that
>>>>>>> might be less complex.
>>>>>>> What if there were a way to copy existing services and override
>> their
>>>>>>> configurations? Unless I'm really stupid, this is not yet
>>>>>>> One rather obvious issue is that the services I'd like to copy
>> depend
>>>>>>> on
>>>>>>> eachother, so there would have to be a method to map them all
to a
>>>>>>> copy.
>>>>>>> Else I would copy a service only to find that it's still depending
>> on
>>>>>>> the
>>>>>>> original's services.
>>>>>>> Constraints:
>>>>>>> The software is supposed to be unaware of the implementation
>>>>>>> but
>>>>>>> it
>>>>>>> may of course be aware of the externally provided services.
>>>>>>> I don't want to copy existing code. Obviously. It would hurt
>>>>>>> reusability.
>>>>>>> Basically, what we're dealing with is a matter of creating
>>>>>>> services (or groups of services) with different configurations.
>>>>>>> So, we have 3 services
>>>>>>> HibernateSessionManager
>>>>>>> HibernateSessionSource
>>>>>>> HibernateEntityPackageManager
>>>>>>> Session
>>>>>>> Now what I would like is to create 3 new services:
>>>>>>> ContentSessionManager
>>>>>>> ContentSessionSource
>>>>>>> ContentEntityPackageManager
>>>>>>> ContentSession
>>>>>>> ProductsSessionManager
>>>>>>> ProductsSessionSource
>>>>>>> ProductsEntityPackageManager
>>>>>>> ProductsSession
>>>>>>> Now I would like a service "ServiceCopier" or something like
>>>>>>> implement: [pseudocode]
>>>>>>> Map<String, String>  content = { "Session" =>  "ContentSession",
>>>>>>> "HibernateSessionManager" =>  "ContentSessionManager",
>>>>>>>  "HibernateSessionSource"=>"ContentSessionSource",
>>>>>>> "HibernateEntityPackageManager"=>"ContentEntityPackageManager"
>>>>>>> Map<String, String>  products = {"Session" =>  "ProductsSession",
>>>>>>> "HibernateSessionManager" =>  "ProductsSessionManager",
>>>>>>>  "HibernateSessionSource"=>"ProductsSessionSource",
>>>>>>> "HibernateEntityPackageManager"=>"PrudctsEntityPackageManager"
>>>>>>> copier.add(first);
>>>>>>> copier.add(second);
>>>>>>> This would happen in the Module, of course. I would also set
>>>>>>> DefaultConfiguration to false and provide my own thingie for
>>> but
>>>>>>> that's simple once the new services are coaxed to use the
>>> contributions
>>>>>>> using their new service id.
>>>>>>> The service builder would construct the three services as normal,
>>>>>>> except
>>>>>>> that whenever ContentSessionManager depends on
>>> HibernateSessionSource,
>>>>>>> it
>>>>>>> will depend on ContentSessionSource instead, et cetera. I can
>>> use
>>>>>>> @InjectService("ContentSession")
>>>>>>> There is one important thing: the contributions from the original
>>>>>>> service
>>>>>>> will have to be included, as well as contributions for the new
>>> service
>>>>>>> id.
>>>>>>> If this would not happen, configurers such as
>>>>>>> PackageNameHibernateConfigurer.java would not be included. The
>> proper
>>>>>>> usage
>>>>>>> of the concept explained here is that a user would not provide
>>>>>>> configuration contributions for the base case, but only for the
>>> derived
>>>>>>> services.
>>>>>>> Hmmm this sounds conceptually a bit like namespaces, but you're
>>>>>>> ahead
>>>>>>> of
>>>>>>> me in experience so I can't really comment on the similarity.
>>>>>>> Anyway, I promised to keep it brief and I doubt I could describe
>>> in
>>>>>>> less
>>>>>>> words. I've described my problem and leave it to you to reply.
>>>>>>> Hoping for an answer,
>>>>>>> Tom van Dijk.
>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>>>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: dev-help@tapestry.apache.org

To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org

View raw message