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 of them (via marker annotations). On Sat, Oct 16, 2010 at 7:56 AM, Tom van Dijk <[email protected]> wrote: > 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 days 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 objects 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 configuration. > > Obviously, because it's a custom object provider, the whole lifecycle 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 feeling I'm > also violating Tapestry principles somewhere. > > > > A different line of thought that I am considering is using a construct like > in the Tapestry / Swing integration package, to create all services. There > is still the issue of the Tapestry/Hibernate (web) integration module > 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 without > 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 without >> 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<[email protected]> 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 Tapestry5 >>> 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 would like >>> is >>> to have two differently configured Session services. Obviously, I want to >>> move on, embrace the future and start using a proper IoC framework. >>> >>> Now I see in the issue system that this (using multiple databases) is >>> unsupported. My question concerns a generalized approach. My first >>> thoughts >>> were on creating some kind of a general Factory service that would 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 possible. >>> >>> 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 classes 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 different >>> 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 that to >>> 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 that, 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 then 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 extra >>> configuration contributions for the base case, but only for the derived >>> services. >>> >>> Hmmm this sounds conceptually a bit like namespaces, but you're way 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 it 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: [email protected] >>> For additional commands, e-mail: [email protected] >>> >>> >> >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > > -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
