You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Tom van Dijk <to...@tvandijk.nl> on 2010/06/02 00:25:42 UTC

Using multiple databases?

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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Wed, 02 Jun 2010 14:48:30 -0300, Piero Sartini <li...@pierosartini.de>  
wrote:

> Anyway, what I would really love to see is that tapestry's core makes
> it easier for others to integrate new persistence strategies.
> @CommitAfter and other stuff could be factored out of the hibernate
> module - its used in every persistence module I've created so far.
> This would be a good start, and could be extended as needed.

That's where my idea of a tapestry-transaction package would come in. It  
would provide the transation annotation (@CommitAfter or another one still  
to be created).

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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


Re: Using multiple databases?

Posted by Piero Sartini <li...@pierosartini.de>.
> Just a matter of bandwidth.  Also, I prefer not to create modules for
> things I'm not actively using. I currently use Hibernate in both my
> client projects, but don't use JPA. I or someone else could throw
> something together, or take a contribution, but I'd prefer to have
> someone who actively maintains and improves whatever library is
> created.

Point taken. I am happy with tapestry-jpa as a seperate module.
It's just that people often say to me: "What? No JPA support?"
Sometimes its hard to explain that there exists a third party module
that is not part of tapestry itself. But I guess we can solve this
with the new homepage and make it more clear that it is totally OK to
use external modules.

Anyway, what I would really love to see is that tapestry's core makes
it easier for others to integrate new persistence strategies.
@CommitAfter and other stuff could be factored out of the hibernate
module - its used in every persistence module I've created so far.
This would be a good start, and could be extended as needed.

To make it short: please don't put new logic into tapestry-hibernate
that could be useful for other persistence strategies as well.

                 Piero

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


Re: Using multiple databases?

Posted by Howard Lewis Ship <hl...@gmail.com>.
Just a matter of bandwidth.  Also, I prefer not to create modules for
things I'm not actively using. I currently use Hibernate in both my
client projects, but don't use JPA. I or someone else could throw
something together, or take a contribution, but I'd prefer to have
someone who actively maintains and improves whatever library is
created.

I've seen in infrastructures that make it very easy to create and
distribute libraries or modules, such as Ruby Gems, you see an awful
lot of incomplete, outdated and orphaned code.

On Wed, Jun 2, 2010 at 9:20 AM, Piero Sartini <li...@pierosartini.de> wrote:
>> 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).
>
> I've thought about implementing this functionality in tapestry-jpa as well.
> With JPA we don't have the problem of the configuration as everything
> is configured inside persistence.xml. Auto discovery is already
> handled by most implementations. No need to do all the configuration
> magic present in the hibernate module.
>
> If you want to introduce some way to handle multiple databases in the
> hibernate module, maybe it would be a good timeframe to create a
> tapestry-persistence module which can be used by other modules like
> tapestry-jpa or tapestry-mongodb as well. I am thinking mainly about
> annotations like @CommitAfter. But the interface to handle multiple
> data sources should be reusable as well.
>
> On a side note, maybe its time for tapestry to get first class JPA2 support?
>
>             Piero
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>



-- 
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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by Piero Sartini <li...@pierosartini.de>.
> 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).

I've thought about implementing this functionality in tapestry-jpa as well.
With JPA we don't have the problem of the configuration as everything
is configured inside persistence.xml. Auto discovery is already
handled by most implementations. No need to do all the configuration
magic present in the hibernate module.

If you want to introduce some way to handle multiple databases in the
hibernate module, maybe it would be a good timeframe to create a
tapestry-persistence module which can be used by other modules like
tapestry-jpa or tapestry-mongodb as well. I am thinking mainly about
annotations like @CommitAfter. But the interface to handle multiple
data sources should be reusable as well.

On a side note, maybe its time for tapestry to get first class JPA2 support?

             Piero

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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Me again, with yet another question.

For the value encoder, I want to
include which session object should be used (e.g. the one with the red
marker, or the one with the blue marker). Now there appears to be no way to
figure this out, except iterating over all session objects and calling
session.contains(object).

Well, I can iterate over all session objects,
but session is a shadowed property of the per-thread manager, which may not
have been realized. Realizing every session is not something we want to do,
so I'm looking for a good way to determine if a session has been realized.
Obviously, I checked out the ServiceActivityScoreboard service.

Now there
are two issues with the scoreboard. I could file issues on them in JIRA but
I'm not sure if the concept is right.
1. I would like to see
ServiceActivity have getMarkers() or a similar construct. Howard's comment
in a different thread about Tapestry moving towards Guice in the sense of
using serviceinterface+markers instead of service id's especially rubbed my
thoughts on this.
2. It appears the ServiceActivity does not track
perthread services as I would expect. The following test case will fail on
the last assertion.

 private Status
getServiceActivityStatus(ServiceActivityScoreboard sb, String serviceId) {

// todo: instead of serviceId, get serviceInterface+markers
 for
(ServiceActivity sa : sb.getServiceActivity()) {
 if
(sa.getServiceId().equals(serviceId)) return sa.getStatus();
 }
 return
null;
 }

 @Test
 public void temporary_test() {
 Registry r =
buildRegistry(HibernateCoreModule.class, RedModule.class,
BlueModule.class);

 r.performRegistryStartup();

 final ObjectLocator
locator = r;
 final ServiceActivityScoreboard sb =
locator.getService(ServiceActivityScoreboard.class);


assertTrue(getServiceActivityStatus(sb, "SessionRed") == Status.DEFINED);


Thread t1 = new Thread(new Runnable() {
 public void run() {
 Session red =
locator.getService(Session.class, Red.class);


assertTrue(getServiceActivityStatus(sb, "SessionRed") == Status.VIRTUAL);


Book myBook = new Book();
 myBook.setAuthor("Robert Jordan");

myBook.setTitle("The Gathering Storm");

 red.persist(myBook);


assertTrue(getServiceActivityStatus(sb, "SessionRed") == Status.REAL);
 }

});

 t1.start();
 try {
 t1.join();
 } catch (InterruptedException ex) {

fail("Interrupted");
 }

 // We are back in the thread that does not have
session red realized
 // In this thread, it should be DEFINED

assertTrue(getServiceActivityStatus(sb, "SessionRed") == Status.DEFINED);

}

I think modifying the service activity stuff to do this right (as in,
right as I see it) should be an easy change. Is my reasoning
correct?

Thanks.


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Next year I'll write a larger book for my master's thesis, okay? :)

Op 29-10-2010 19:39, Howard Lewis Ship schreef:
> My brain is now overloaded.
>
> On Thu, Oct 28, 2010 at 7:33 AM, Tom van Dijk<to...@tvandijk.nl>  wrote:
>> Hi,
>>
>> I'm discovering some interesting implications of dynamic services.
>>
>> In hibernate-core, building dynamic services causes at least two services to
>> be realized.
>>
>> Let us assume that dynamic services are created based upon a contribution to
>> a service.
>> For example, dynamic services of hibernate-core are created based upon
>> contributions to the service HibernateMarkerConfiguration. This service is
>> injected into the dynamic contributor method (parameter injection)
>> The use of a HibernateMarkerConfiguration service could be considered
>> bending the semantics of a "service" a bit, since the service doesn't do
>> anything apart from providing the markers.
>> However, there really is only one way right now to contribute the markers,
>> and that's by contributing them to a service.
>>
>> The real "problem", however, is not that I'm using a service.
>>
>> The real problem is that in order to realize the
>> HibernateMarkerConfiguration service, other services have to be realized as
>> well, in particular the MasterObjectProvider and ServiceOverride. This means
>> that after the collectDynamicServices() and collectDynamicContributions()
>> steps, no dynamic contributions can be done to MasterObjectProvider and
>> ServiceOverride. Worse, if your contributions to ServiceOverride depend on
>> HibernateMarkerConfiguration or something like that, there is a recursion
>> error. Obviously, there's addInstance() to deal with this, but this will not
>> solve the problem that no new contributions can be done by dynamic services.
>> In our case it's even worse, since we have a static contribution to
>> ServiceOverride which depends on HibernateMarkerConfiguration to figure out
>> whether there are any markers. Voila, recursion. (See appendix below)
>>
>> The idea is that dynamic service contributors could use injected parameters
>> for their building, to increase expressivity.
>>
>> The implication of this is that a combination of modules can cause errors,
>> while each individual module works fine. Maybe module X depends on service S
>> to dynamically create classes, and module Y wants to add (dynamic)
>> contributions to service S. Independently, these modules can be in the
>> registry, but their combination will fail, because the service is realized
>> before the dynamic contribution is done. ((Note: in my current
>> implementation, this won't even be noticed by the Registry, because there is
>> no checking whether dynamic contributions are done to realized services))
>>
>> Fill in for X, Hibernate-core, for Y, Hibernate, and for S the
>> ServiceOverride service (Where ServiceOverride elementOf dependencies(X),
>> due to the injection of HibernateMarkerConfiguration depending on
>> MasterObjectProvider to be realized which depends on ServiceOverride to be
>> realized) and we nearly have our case**. It would even be a problem if X and
>> Y are equal.
>>
>> There are several ways to cope with the issue.
>>
>>
>>
>> POSSIBLE SOLUTION 1
>> A. Allow updating the configuration of services. Several possible strategies
>> include: rebuilding the service when the configuration is updated; calling
>> an updateConfiguration() method in the implementation class. Note that
>> updating the configuration always means adding a new configuration entry.
>> B. Generate an error when there is a dynamic contribution to a service that
>> has already been realized and that is not update-able according to A.
>> C. Allow injection of objects into Dynamic Service Contributors and Dynamic
>> Contribution Contributors.
>>
>> This does not mean every service must be modified to allow
>> rebuilding/updateConfiguration() calls. By default, services can be "not
>> update-able". Then, whenever users have clashes, we could modify services to
>> be update-able. For example, MasterObjectProvider and ServiceOverride could
>> possibly be made update-able. We need to design the syntax for this update
>> idea, possibly defining a new annotation to services or service
>> implementations ("@Updateable", with an enum Updating.PROHIBIT,
>> Updating.REBUILD, Updating.METHOD; in the last case exactly one public
>> method in the implementation must have the @ConfigurationUpdate annotation
>> OR be named updateConfiguration)
>>
>>
>>
>> POSSIBLE SOLUTION 2
>> No injection of objects into Dynamic Service Contributors and Dynamic
>> Contribution Contributors. A different mechanic must be found to contribute
>> to dynamic services/contributions. Perhaps Dynamic Services/Contributions
>> could be identified using a "Dynamic id" (which can be shared by different
>> dynamic contributors) and which other classes can contribute to.
>> This will severly limit the options for dynamic service/contribution
>> contributions, as they may not have injected services (or something like the
>> ObjectLocator) as parameters.
>> This means no services will be realized during the dynamic part.
>> This will not mean that a HibernateMarkerConfiguration service will not
>> exist; it will still exist because there could be static services that may
>> want to know which database configurations there are (e.g. HibernateUtil in
>> my solution).
>>
>>
>>
>> With solution 1, this might mean more work and maintenance of existing
>> services, although good test cases for every modified service will make this
>> process much smoother.
>> With solution 2, this might severely limit the options for dynamic services.
>>
>>
>> The use case of our multiple database problem can be generalized to the
>> problem of services with multiple configurations. Essentially that's what we
>> have here: 6 services (hibernate-core) that have N configurations (e.g. Red
>> and Blue in the appendix).
>>
>> Perhaps there are other use cases that need to be considered in the context
>> of dynamic services/contributions. An example of this is Spring integration,
>> which I have not looked into yet. (One problem there is that discovery of
>> spring objects relies on the ServletContext object, which set in the
>> application globals by tapestry-core during startup... but perhaps core
>> could be modified to contribute the ServletContext object in some other way,
>> so it can be discovered by a dynamic solution - until that is solved,
>> tapestry-spring has to use a TapestyFilter subclass).
>>
>>
>>
>>
>> POSSIBLE SOLUTION 3
>>
>> Alternatively, instead of this dynamic service jungle, we could consider
>> only solving the "services with multiple configurations" problem by using a
>> @MultipleConfigurations("MCid") annotation.
>> Modules could statically contribute to a MCid using some syntax.
>> (@ContributeMultipleConfiguration("MCid") Class[] contributeMarkers() {
>> return new Class[] {Red.class, Blue.class} })
>> If placed on a builder, this means "for every contributed marker, generate a
>> service with additional marker; if no markers contributed, generate a
>> service without additional markers;" and the marker (or null if no markers
>> defined anywhere) would be injected into the build method.
>> If placed on a contributor, this means exactly the same.
>> Alternatively, contributors may also have the parameter
>> ("MultipleConfiguration") (with subclasses MultipleMappedConfiguration,
>> MultipleOrderedConfiguration....) which exposes the Class[] array of
>> markers.
>>
>> We would have to consider what to do with the case where no markers are
>> contributed to a MultipleConfiguration. In the solution I just described, it
>> would fall back to generating a single service. However, maybe one would
>> always want to create the "no markers" service, using ServiceOverride to set
>> the default service implementation to the "null" service.... e.g. with
>> multiple database, if {Red,Blue} are contributed, create Session, @Red
>> SessionRed and @Blue SessionBlue; if no markers are defined, use Session.
>> (My current implementation is: if {} is contributed, create Session; if
>> {A,B,C...} is contributed, create @A SessionA, @B SessionB, @C SessionC,
>> ...)
>>
>>
>>
>>
>> TLDR;
>> collecting dynamic services/contributions cause services to be realized,
>> causing problems with contributions, as well as causing recursion.
>> solution 1: allow services to be updated when there are new contributions
>> solution 2: use a different mechanism to contribute configuration to dynamic
>> service contributors and do not allow services to be realized during
>> collection
>> solution 3: do not allow dynamic services, instead create a syntax for the
>> "services with multiple configurations" concept
>>
>>
>> I would love feedback. Can't make all the decisions on my own, I'm too
>> inexperienced for that.
>> Also, there may be even more things I've overlooked. Please let me know if
>> there are more issues.
>>
>> Tom.
>>
>>
>>
>> ** I say nearly, because my current implementation has
>> HibernateMarkerConfiguration injected into contributeServiceOverride, which
>> obviously won't work. I could modify this to create a dynamiccontribution,
>> contributing to Service Override. In this case, the contribution will be
>> lost.
>>
>>
>> Appendix:
>> Registry changes by dynamics
>>                    AspectDecorator : DEFINED =>  VIRTUAL
>>       HibernateMarkerConfiguration : DEFINED =>  REAL
>>               MasterObjectProvider : DEFINED =>  REAL
>>                    ServiceOverride : DEFINED =>  REAL
>>                       SymbolSource : DEFINED =>  VIRTUAL
>>                        TypeCoercer : DEFINED =>  VIRTUAL
>>     DefaultHibernateConfigurerBlue :         =>  DEFINED
>>      DefaultHibernateConfigurerRed :         =>  DEFINED
>> HibernateEntityPackageManagerBlue :         =>  DEFINED
>>   HibernateEntityPackageManagerRed :         =>  DEFINED
>>        HibernateSessionManagerBlue :         =>  DEFINED
>>         HibernateSessionManagerRed :         =>  DEFINED
>>         HibernateSessionSourceBlue :         =>  DEFINED
>>          HibernateSessionSourceRed :         =>  DEFINED
>> PackageNameHibernateConfigurerBlue :         =>  DEFINED
>> PackageNameHibernateConfigurerRed :         =>  DEFINED
>>                      SessionBlue :         =>  DEFINED
>>                       SessionRed :         =>  DEFINED
>>
>>
>>
>>
>>
>>
>> Op 27-10-2010 2:15, Tom van Dijk schreef:
>>> For your pleasure, I implemented the "abstract class" alternative, as a
>>> different branch.
>>>
>>>
>>> There are now a number of branches on my git
>>>
>>>              trunk
>>>                |
>>>             fix1326 (fixes TAP5-1326)
>>>                |
>>> [2 commits without a branch] (fixes TAP5-1321 and TAP5-1320)
>>>     /                 \
>>>    /                   \
>>> iocmod2               iocmod3     (fixes TAP5-1313, dynamic services)
>>>    |                    |
>>> [commit]              [commit]
>>>    |                    |
>>> hibmod2               hibmod3     (fixes TAP5-48, multiple databases)
>>>
>>> the "2" branch uses annotated services
>>> the "3" branch uses the abstract class
>>>
>>> Maybe I should learn to "tag" instead of making a load of branches :)
>>>
>>> Tom.
>>>
>>> ---------------------------------------------------------------------
>>> 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


Re: Using multiple databases?

Posted by Howard Lewis Ship <hl...@gmail.com>.
My brain is now overloaded.

On Thu, Oct 28, 2010 at 7:33 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
> Hi,
>
> I'm discovering some interesting implications of dynamic services.
>
> In hibernate-core, building dynamic services causes at least two services to
> be realized.
>
> Let us assume that dynamic services are created based upon a contribution to
> a service.
> For example, dynamic services of hibernate-core are created based upon
> contributions to the service HibernateMarkerConfiguration. This service is
> injected into the dynamic contributor method (parameter injection)
> The use of a HibernateMarkerConfiguration service could be considered
> bending the semantics of a "service" a bit, since the service doesn't do
> anything apart from providing the markers.
> However, there really is only one way right now to contribute the markers,
> and that's by contributing them to a service.
>
> The real "problem", however, is not that I'm using a service.
>
> The real problem is that in order to realize the
> HibernateMarkerConfiguration service, other services have to be realized as
> well, in particular the MasterObjectProvider and ServiceOverride. This means
> that after the collectDynamicServices() and collectDynamicContributions()
> steps, no dynamic contributions can be done to MasterObjectProvider and
> ServiceOverride. Worse, if your contributions to ServiceOverride depend on
> HibernateMarkerConfiguration or something like that, there is a recursion
> error. Obviously, there's addInstance() to deal with this, but this will not
> solve the problem that no new contributions can be done by dynamic services.
> In our case it's even worse, since we have a static contribution to
> ServiceOverride which depends on HibernateMarkerConfiguration to figure out
> whether there are any markers. Voila, recursion. (See appendix below)
>
> The idea is that dynamic service contributors could use injected parameters
> for their building, to increase expressivity.
>
> The implication of this is that a combination of modules can cause errors,
> while each individual module works fine. Maybe module X depends on service S
> to dynamically create classes, and module Y wants to add (dynamic)
> contributions to service S. Independently, these modules can be in the
> registry, but their combination will fail, because the service is realized
> before the dynamic contribution is done. ((Note: in my current
> implementation, this won't even be noticed by the Registry, because there is
> no checking whether dynamic contributions are done to realized services))
>
> Fill in for X, Hibernate-core, for Y, Hibernate, and for S the
> ServiceOverride service (Where ServiceOverride elementOf dependencies(X),
> due to the injection of HibernateMarkerConfiguration depending on
> MasterObjectProvider to be realized which depends on ServiceOverride to be
> realized) and we nearly have our case**. It would even be a problem if X and
> Y are equal.
>
> There are several ways to cope with the issue.
>
>
>
> POSSIBLE SOLUTION 1
> A. Allow updating the configuration of services. Several possible strategies
> include: rebuilding the service when the configuration is updated; calling
> an updateConfiguration() method in the implementation class. Note that
> updating the configuration always means adding a new configuration entry.
> B. Generate an error when there is a dynamic contribution to a service that
> has already been realized and that is not update-able according to A.
> C. Allow injection of objects into Dynamic Service Contributors and Dynamic
> Contribution Contributors.
>
> This does not mean every service must be modified to allow
> rebuilding/updateConfiguration() calls. By default, services can be "not
> update-able". Then, whenever users have clashes, we could modify services to
> be update-able. For example, MasterObjectProvider and ServiceOverride could
> possibly be made update-able. We need to design the syntax for this update
> idea, possibly defining a new annotation to services or service
> implementations ("@Updateable", with an enum Updating.PROHIBIT,
> Updating.REBUILD, Updating.METHOD; in the last case exactly one public
> method in the implementation must have the @ConfigurationUpdate annotation
> OR be named updateConfiguration)
>
>
>
> POSSIBLE SOLUTION 2
> No injection of objects into Dynamic Service Contributors and Dynamic
> Contribution Contributors. A different mechanic must be found to contribute
> to dynamic services/contributions. Perhaps Dynamic Services/Contributions
> could be identified using a "Dynamic id" (which can be shared by different
> dynamic contributors) and which other classes can contribute to.
> This will severly limit the options for dynamic service/contribution
> contributions, as they may not have injected services (or something like the
> ObjectLocator) as parameters.
> This means no services will be realized during the dynamic part.
> This will not mean that a HibernateMarkerConfiguration service will not
> exist; it will still exist because there could be static services that may
> want to know which database configurations there are (e.g. HibernateUtil in
> my solution).
>
>
>
> With solution 1, this might mean more work and maintenance of existing
> services, although good test cases for every modified service will make this
> process much smoother.
> With solution 2, this might severely limit the options for dynamic services.
>
>
> The use case of our multiple database problem can be generalized to the
> problem of services with multiple configurations. Essentially that's what we
> have here: 6 services (hibernate-core) that have N configurations (e.g. Red
> and Blue in the appendix).
>
> Perhaps there are other use cases that need to be considered in the context
> of dynamic services/contributions. An example of this is Spring integration,
> which I have not looked into yet. (One problem there is that discovery of
> spring objects relies on the ServletContext object, which set in the
> application globals by tapestry-core during startup... but perhaps core
> could be modified to contribute the ServletContext object in some other way,
> so it can be discovered by a dynamic solution - until that is solved,
> tapestry-spring has to use a TapestyFilter subclass).
>
>
>
>
> POSSIBLE SOLUTION 3
>
> Alternatively, instead of this dynamic service jungle, we could consider
> only solving the "services with multiple configurations" problem by using a
> @MultipleConfigurations("MCid") annotation.
> Modules could statically contribute to a MCid using some syntax.
> (@ContributeMultipleConfiguration("MCid") Class[] contributeMarkers() {
> return new Class[] {Red.class, Blue.class} })
> If placed on a builder, this means "for every contributed marker, generate a
> service with additional marker; if no markers contributed, generate a
> service without additional markers;" and the marker (or null if no markers
> defined anywhere) would be injected into the build method.
> If placed on a contributor, this means exactly the same.
> Alternatively, contributors may also have the parameter
> ("MultipleConfiguration") (with subclasses MultipleMappedConfiguration,
> MultipleOrderedConfiguration....) which exposes the Class[] array of
> markers.
>
> We would have to consider what to do with the case where no markers are
> contributed to a MultipleConfiguration. In the solution I just described, it
> would fall back to generating a single service. However, maybe one would
> always want to create the "no markers" service, using ServiceOverride to set
> the default service implementation to the "null" service.... e.g. with
> multiple database, if {Red,Blue} are contributed, create Session, @Red
> SessionRed and @Blue SessionBlue; if no markers are defined, use Session.
> (My current implementation is: if {} is contributed, create Session; if
> {A,B,C...} is contributed, create @A SessionA, @B SessionB, @C SessionC,
> ...)
>
>
>
>
> TLDR;
> collecting dynamic services/contributions cause services to be realized,
> causing problems with contributions, as well as causing recursion.
> solution 1: allow services to be updated when there are new contributions
> solution 2: use a different mechanism to contribute configuration to dynamic
> service contributors and do not allow services to be realized during
> collection
> solution 3: do not allow dynamic services, instead create a syntax for the
> "services with multiple configurations" concept
>
>
> I would love feedback. Can't make all the decisions on my own, I'm too
> inexperienced for that.
> Also, there may be even more things I've overlooked. Please let me know if
> there are more issues.
>
> Tom.
>
>
>
> ** I say nearly, because my current implementation has
> HibernateMarkerConfiguration injected into contributeServiceOverride, which
> obviously won't work. I could modify this to create a dynamiccontribution,
> contributing to Service Override. In this case, the contribution will be
> lost.
>
>
> Appendix:
> Registry changes by dynamics
>                   AspectDecorator : DEFINED => VIRTUAL
>      HibernateMarkerConfiguration : DEFINED => REAL
>              MasterObjectProvider : DEFINED => REAL
>                   ServiceOverride : DEFINED => REAL
>                      SymbolSource : DEFINED => VIRTUAL
>                       TypeCoercer : DEFINED => VIRTUAL
>    DefaultHibernateConfigurerBlue :         => DEFINED
>     DefaultHibernateConfigurerRed :         => DEFINED
> HibernateEntityPackageManagerBlue :         => DEFINED
>  HibernateEntityPackageManagerRed :         => DEFINED
>       HibernateSessionManagerBlue :         => DEFINED
>        HibernateSessionManagerRed :         => DEFINED
>        HibernateSessionSourceBlue :         => DEFINED
>         HibernateSessionSourceRed :         => DEFINED
> PackageNameHibernateConfigurerBlue :         => DEFINED
> PackageNameHibernateConfigurerRed :         => DEFINED
>                     SessionBlue :         => DEFINED
>                      SessionRed :         => DEFINED
>
>
>
>
>
>
> Op 27-10-2010 2:15, Tom van Dijk schreef:
>>
>> For your pleasure, I implemented the "abstract class" alternative, as a
>> different branch.
>>
>>
>> There are now a number of branches on my git
>>
>>             trunk
>>               |
>>            fix1326 (fixes TAP5-1326)
>>               |
>> [2 commits without a branch] (fixes TAP5-1321 and TAP5-1320)
>>    /                 \
>>   /                   \
>> iocmod2               iocmod3     (fixes TAP5-1313, dynamic services)
>>   |                    |
>> [commit]              [commit]
>>   |                    |
>> hibmod2               hibmod3     (fixes TAP5-48, multiple databases)
>>
>> the "2" branch uses annotated services
>> the "3" branch uses the abstract class
>>
>> Maybe I should learn to "tag" instead of making a load of branches :)
>>
>> Tom.
>>
>> ---------------------------------------------------------------------
>> 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
>
>



-- 
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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Hi,

I'm discovering some interesting implications of dynamic services.

In hibernate-core, building dynamic services causes at least two 
services to be realized.

Let us assume that dynamic services are created based upon a 
contribution to a service.
For example, dynamic services of hibernate-core are created based upon 
contributions to the service HibernateMarkerConfiguration. This service 
is injected into the dynamic contributor method (parameter injection)
The use of a HibernateMarkerConfiguration service could be considered 
bending the semantics of a "service" a bit, since the service doesn't do 
anything apart from providing the markers.
However, there really is only one way right now to contribute the 
markers, and that's by contributing them to a service.

The real "problem", however, is not that I'm using a service.

The real problem is that in order to realize the 
HibernateMarkerConfiguration service, other services have to be realized 
as well, in particular the MasterObjectProvider and ServiceOverride. 
This means that after the collectDynamicServices() and 
collectDynamicContributions() steps, no dynamic contributions can be 
done to MasterObjectProvider and ServiceOverride. Worse, if your 
contributions to ServiceOverride depend on HibernateMarkerConfiguration 
or something like that, there is a recursion error. Obviously, there's 
addInstance() to deal with this, but this will not solve the problem 
that no new contributions can be done by dynamic services. In our case 
it's even worse, since we have a static contribution to ServiceOverride 
which depends on HibernateMarkerConfiguration to figure out whether 
there are any markers. Voila, recursion. (See appendix below)

The idea is that dynamic service contributors could use injected 
parameters for their building, to increase expressivity.

The implication of this is that a combination of modules can cause 
errors, while each individual module works fine. Maybe module X depends 
on service S to dynamically create classes, and module Y wants to add 
(dynamic) contributions to service S. Independently, these modules can 
be in the registry, but their combination will fail, because the service 
is realized before the dynamic contribution is done. ((Note: in my 
current implementation, this won't even be noticed by the Registry, 
because there is no checking whether dynamic contributions are done to 
realized services))

Fill in for X, Hibernate-core, for Y, Hibernate, and for S the 
ServiceOverride service (Where ServiceOverride elementOf 
dependencies(X), due to the injection of HibernateMarkerConfiguration 
depending on MasterObjectProvider to be realized which depends on 
ServiceOverride to be realized) and we nearly have our case**. It would 
even be a problem if X and Y are equal.

There are several ways to cope with the issue.



POSSIBLE SOLUTION 1
A. Allow updating the configuration of services. Several possible 
strategies include: rebuilding the service when the configuration is 
updated; calling an updateConfiguration() method in the implementation 
class. Note that updating the configuration always means adding a new 
configuration entry.
B. Generate an error when there is a dynamic contribution to a service 
that has already been realized and that is not update-able according to A.
C. Allow injection of objects into Dynamic Service Contributors and 
Dynamic Contribution Contributors.

This does not mean every service must be modified to allow 
rebuilding/updateConfiguration() calls. By default, services can be "not 
update-able". Then, whenever users have clashes, we could modify 
services to be update-able. For example, MasterObjectProvider and 
ServiceOverride could possibly be made update-able. We need to design 
the syntax for this update idea, possibly defining a new annotation to 
services or service implementations ("@Updateable", with an enum 
Updating.PROHIBIT, Updating.REBUILD, Updating.METHOD; in the last case 
exactly one public method in the implementation must have the 
@ConfigurationUpdate annotation OR be named updateConfiguration)



POSSIBLE SOLUTION 2
No injection of objects into Dynamic Service Contributors and Dynamic 
Contribution Contributors. A different mechanic must be found to 
contribute to dynamic services/contributions. Perhaps Dynamic 
Services/Contributions could be identified using a "Dynamic id" (which 
can be shared by different dynamic contributors) and which other classes 
can contribute to.
This will severly limit the options for dynamic service/contribution 
contributions, as they may not have injected services (or something like 
the ObjectLocator) as parameters.
This means no services will be realized during the dynamic part.
This will not mean that a HibernateMarkerConfiguration service will not 
exist; it will still exist because there could be static services that 
may want to know which database configurations there are (e.g. 
HibernateUtil in my solution).



With solution 1, this might mean more work and maintenance of existing 
services, although good test cases for every modified service will make 
this process much smoother.
With solution 2, this might severely limit the options for dynamic services.


The use case of our multiple database problem can be generalized to the 
problem of services with multiple configurations. Essentially that's 
what we have here: 6 services (hibernate-core) that have N 
configurations (e.g. Red and Blue in the appendix).

Perhaps there are other use cases that need to be considered in the 
context of dynamic services/contributions. An example of this is Spring 
integration, which I have not looked into yet. (One problem there is 
that discovery of spring objects relies on the ServletContext object, 
which set in the application globals by tapestry-core during startup... 
but perhaps core could be modified to contribute the ServletContext 
object in some other way, so it can be discovered by a dynamic solution 
- until that is solved, tapestry-spring has to use a TapestyFilter 
subclass).




POSSIBLE SOLUTION 3

Alternatively, instead of this dynamic service jungle, we could consider 
only solving the "services with multiple configurations" problem by 
using a @MultipleConfigurations("MCid") annotation.
Modules could statically contribute to a MCid using some syntax. 
(@ContributeMultipleConfiguration("MCid") Class[] contributeMarkers() { 
return new Class[] {Red.class, Blue.class} })
If placed on a builder, this means "for every contributed marker, 
generate a service with additional marker; if no markers contributed, 
generate a service without additional markers;" and the marker (or null 
if no markers defined anywhere) would be injected into the build method.
If placed on a contributor, this means exactly the same.
Alternatively, contributors may also have the parameter 
("MultipleConfiguration") (with subclasses MultipleMappedConfiguration, 
MultipleOrderedConfiguration....) which exposes the Class[] array of 
markers.

We would have to consider what to do with the case where no markers are 
contributed to a MultipleConfiguration. In the solution I just 
described, it would fall back to generating a single service. However, 
maybe one would always want to create the "no markers" service, using 
ServiceOverride to set the default service implementation to the "null" 
service.... e.g. with multiple database, if {Red,Blue} are contributed, 
create Session, @Red SessionRed and @Blue SessionBlue; if no markers are 
defined, use Session. (My current implementation is: if {} is 
contributed, create Session; if {A,B,C...} is contributed, create @A 
SessionA, @B SessionB, @C SessionC, ...)




TLDR;
collecting dynamic services/contributions cause services to be realized, 
causing problems with contributions, as well as causing recursion.
solution 1: allow services to be updated when there are new contributions
solution 2: use a different mechanism to contribute configuration to 
dynamic service contributors and do not allow services to be realized 
during collection
solution 3: do not allow dynamic services, instead create a syntax for 
the "services with multiple configurations" concept


I would love feedback. Can't make all the decisions on my own, I'm too 
inexperienced for that.
Also, there may be even more things I've overlooked. Please let me know 
if there are more issues.

Tom.



** I say nearly, because my current implementation has 
HibernateMarkerConfiguration injected into contributeServiceOverride, 
which obviously won't work. I could modify this to create a 
dynamiccontribution, contributing to Service Override. In this case, the 
contribution will be lost.


Appendix:
Registry changes by dynamics
                    AspectDecorator : DEFINED => VIRTUAL
       HibernateMarkerConfiguration : DEFINED => REAL
               MasterObjectProvider : DEFINED => REAL
                    ServiceOverride : DEFINED => REAL
                       SymbolSource : DEFINED => VIRTUAL
                        TypeCoercer : DEFINED => VIRTUAL
     DefaultHibernateConfigurerBlue :         => DEFINED
      DefaultHibernateConfigurerRed :         => DEFINED
HibernateEntityPackageManagerBlue :         => DEFINED
   HibernateEntityPackageManagerRed :         => DEFINED
        HibernateSessionManagerBlue :         => DEFINED
         HibernateSessionManagerRed :         => DEFINED
         HibernateSessionSourceBlue :         => DEFINED
          HibernateSessionSourceRed :         => DEFINED
PackageNameHibernateConfigurerBlue :         => DEFINED
PackageNameHibernateConfigurerRed :         => DEFINED
                      SessionBlue :         => DEFINED
                       SessionRed :         => DEFINED






Op 27-10-2010 2:15, Tom van Dijk schreef:
> For your pleasure, I implemented the "abstract class" alternative, as a
> different branch.
>
>
> There are now a number of branches on my git
>
>              trunk
>                |
>             fix1326 (fixes TAP5-1326)
>                |
> [2 commits without a branch] (fixes TAP5-1321 and TAP5-1320)
>     /                 \
>    /                   \
> iocmod2               iocmod3     (fixes TAP5-1313, dynamic services)
>    |                    |
> [commit]              [commit]
>    |                    |
> hibmod2               hibmod3     (fixes TAP5-48, multiple databases)
>
> the "2" branch uses annotated services
> the "3" branch uses the abstract class
>
> Maybe I should learn to "tag" instead of making a load of branches :)
>
> Tom.
>
> ---------------------------------------------------------------------
> 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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
For your pleasure, I implemented the "abstract class" alternative, as a
different branch.


There are now a number of branches on my git

            trunk
              |
           fix1326 (fixes TAP5-1326)
              |
[2 commits without a branch] (fixes TAP5-1321 and TAP5-1320)
   /                 \
  /                   \
iocmod2               iocmod3     (fixes TAP5-1313, dynamic services)
  |                    |
[commit]              [commit]
  |                    |
hibmod2               hibmod3     (fixes TAP5-48, multiple databases)
                                                   
the "2" branch uses annotated services
the "3" branch uses the abstract class

Maybe I should learn to "tag" instead of making a load of branches :)

Tom.

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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Hi,

I'd like feedback on a design choice. 

The current implementation of dynamic services uses annotations, but I'm
doing some iteration on the design and came up with this alternative idea
that might be cleaner.



ALTERNATIVE #1

DynamicService (which is returned in a collection by a
@DynamicServiceContributor method in the module) is defined as follows:

public interface DynamicService {
    Set<Annotation> getAnnotations();
}

The idea is that a DynamicService also implements a build(...) method,
which can be buildASDFASDF(...) or @Annotations build(...) and the
getAnnotations method allows adding dynamic annotations, like Markers or
the service id. The service interface is derived from the return type of
the build(...) method.

A downside to this is that you need to construct Annotation objects. For
this I could add a new service in IoC (and in fact, the tip of my git repo
points to a commit that adds this service), DynamicAnnotationHelper, with
methods createMarkerAnnotation(Class... markers),
createEagerLoadAnnotation(), createScopeAnnotation(String value),
createServiceIdAnnotation(String serviceId),
createPreventMethodDecorationAnnotation(). This service uses the
ClassFactory (javassist) to create Annotation objects, including
hashCode(), toString(), equals() and stuff like that. It's quite complex,
but I got something that works and even a couple of test cases, comparing
them to ordinary annotations (hashCode(), equals() work as well).

A plus to this is that it's perhaps more dynamic.




ALTERNATIVE #2

public interface DynamicService {
    Set<Class> getMarkers(); // may be null
    String getServiceId(); // required
    String getScope(); // may be null
    boolean getEagerLoad(); // return false by default (could use Boolean
and allow null)
    boolean getPreventServiceDecoration(); // return false by default
(could use Boolean and allow null)
}

Now there also needs to be a build() method of course, but its annotations
are ignored and it shouldn't have a buildASDFASDF() format, because that's
ignored too. The build() method may have any number of (to be injected)
parameters, just like any other build method.

Another alternative is:

public abstract class DynamicService {
    public abstract String getServiceId();
    public Set<Class>getMarkers() { return null; }
    public String getScope() { return null; }
    public boolean getEagerLoad() { return false; }
    public boolean getPreventServiceDecoration() { return false; }
}

Either way, this saves the complexity of creating annotation objects on
the fly (which is complex and doesn't really serve a purpose because they
are only an indirect method of defining markers, service ids, scope, etc,
anyway - there is no real added semantics or expressivity)

The downside is that if there is new functionality (e.g. a new
annotation), the interface must be changed as well, hurting compatibility. 

This can be solved by using an abstract class DynamicService with default
values. If the DynamicService abstract class would be updated with extra
functionality, backward compatibility could be preserved. An alternative to
using abstract classes would be to add new interfaces when new
functionality is added: DynamicService2, DynamicService3, etc just like
with the ModuleDefs.

Another upside of using an abstract class is that not every method needs
to be implemented, only serviceId and build() are really required.





Basically, that lists most of the pros and cons I can come up with right
now. 

So:
#1 = use annotations
#2a = use interface 
#2b = use abstract class 

Considering that we can always create a DynamicService2 interface and
provide toDynamicService2() methods, I'm leaning towards #2a for the
following reasons:
* #1 adds too much unnecessary complexity
* interfaces are preferred above abstract classes (this is just intuition
speaking)

However, #2b also appeals for not requiring every method to be
implemented.

I'm also not sure if it is currently possible to add new
annotations/functionality to the builder methods without modifying the IoC.

Any thoughts?


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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Status update: 

I only need proper test cases for multiple databases, but I got a working
webapp that uses a number of different databases and on the surface it
appears to work. Hurray.

The setup of this webapp:

* package entities.one and entities.two, with a couple of entities in each
package
* marker annotations One, Two and Three
* configuration files hibernate-one.cfg.xml, hibernate-two.cfg.xml and
hibernate-three.cfg.xml

* module:

    public static void contributeHibernateMarkerConfiguration(
            Configuration<Class> configuration) {
        configuration.add(One.class);
        configuration.add(Two.class);
        configuration.add(Three.class);
    }

    public static void contributeHibernateEntityPackageManagerThree(
            Configuration<String> configuration
            ) {
        configuration.add("nl.tvandijk.entities.one");
    }

    @Match("Test")
    public static void adviseStuff(HibernateTransactionAdvisor advisor,
            MethodAdviceReceiver receiver) {
        advisor.addTransactionCommitAdvice(receiver);
    }

* some pages with CommitAfter annotations
* a Test interface with implementation and CommitAfter annotations.

The interpretation of CommitAfter is as follows:
@CommitAfter ({One.class, Two.class}) = apply pattern for databases One,
Two.
@CommitAfter = apply pattern for unmarked database (if no markers
contributed)
             = apply pattern to all databases (otherwise)

There is a restriction on the markers. The must be unique in
simplename-lowercase. The class.getSimpleName().toLowerCase() is used as an
identifier in several places, most importantly (on the top of my head) the
configuration-«identifier».cfg.xml and in the entity value encoder. Because
iirc Tapestry requires a URL to be case insensitive, I'm just using
equalsIgnoreCase and toLowerCase.

I asked Josh to pull from my git repo again for code review. You can also
pull from my git if you prefer that
(git://hetdiana.homeip.net/tapestry5.git branch hibmod2)

I "solved" the ServiceOverride question by only overriding the Session if
no markers are contributed. If markers are contributed to
HibernateMarkerConfiguration, no service overrides are contributed. (( I'm
still not sure if it wouldn't be a cleaner solution if the third party just
uses markers properly, but if I get this correct, the service override
means "default : use mine" instead of "default : generate error" whenever
no markers are used? ))

Idea: maybe a @Contribute(serviceInterface, markers) might be useful. As
well as probably dozens of other places where a serviceId is used right now
instead of a serviceInterface+markers reference.

Regards,
Tom.

On Sat, 23 Oct 2010 08:28:41 -0700, Howard Lewis Ship <hl...@gmail.com>
wrote:
> ServiceOverride is for the case where there are no marker annotation
> but there is an ambiguity which most often happens when overriding an
> existing service.
> 
> On Sat, Oct 23, 2010 at 5:28 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
>> Regarding this ServiceOverride, I am still not sure about the
semantics.
>>
>> How would I change this for multiple services? Is there perhaps another
>> way to solve TAPESTRY-2615?
>>
>> Regarding the rest of the changes: my git now contains an update which
>> implements nearly everything.
>> What I did not do yet:
>> - HibernateGridDatasource
>> - Statistics page
>> - Test cases for multiple databases
>>
>> Tom.
>>


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


Re: Using multiple databases?

Posted by Howard Lewis Ship <hl...@gmail.com>.
ServiceOverride is for the case where there are no marker annotation
but there is an ambiguity which most often happens when overriding an
existing service.

On Sat, Oct 23, 2010 at 5:28 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
> Regarding this ServiceOverride, I am still not sure about the semantics.
>
> How would I change this for multiple services? Is there perhaps another
> way to solve TAPESTRY-2615?
>
> Regarding the rest of the changes: my git now contains an update which
> implements nearly everything.
> What I did not do yet:
> - HibernateGridDatasource
> - Statistics page
> - Test cases for multiple databases
>
> Tom.
>
> On Fri, 22 Oct 2010 10:11:38 -0700, Howard Lewis Ship <hl...@gmail.com>
> wrote:
>> Yes, it's because of a 3rd party library that adds support for
>> HibernateSearch and it's FullTextSearchSession (which extends from
>> Session). https://issues.apache.org/jira/browse/TAPESTRY-2615
>>
>> It should probably be switched to use ServiceOverride, as Alias is
>> deprecated.
>>
>> On Fri, Oct 22, 2010 at 4:42 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
>>> Can someone explain to me why the tapestry-hibernate module contributes
>>> to
>>> Alias?
>>>
>>> public static void contributeAlias(Configuration<AliasContribution>
>>> configuration, @HibernateCore Session session)
>>>    {
>>>        configuration.add(AliasContribution.create(Session.class,
>>> session));
>>>    }
>>>
>>> Does anything break if it's not there?
>>>
>>> ---------------------------------------------------------------------
>>> 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
>
>



-- 
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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Regarding this ServiceOverride, I am still not sure about the semantics.

How would I change this for multiple services? Is there perhaps another
way to solve TAPESTRY-2615?

Regarding the rest of the changes: my git now contains an update which
implements nearly everything.
What I did not do yet:
- HibernateGridDatasource
- Statistics page
- Test cases for multiple databases

Tom.

On Fri, 22 Oct 2010 10:11:38 -0700, Howard Lewis Ship <hl...@gmail.com>
wrote:
> Yes, it's because of a 3rd party library that adds support for
> HibernateSearch and it's FullTextSearchSession (which extends from
> Session). https://issues.apache.org/jira/browse/TAPESTRY-2615
> 
> It should probably be switched to use ServiceOverride, as Alias is
> deprecated.
> 
> On Fri, Oct 22, 2010 at 4:42 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
>> Can someone explain to me why the tapestry-hibernate module contributes
>> to
>> Alias?
>>
>> public static void contributeAlias(Configuration<AliasContribution>
>> configuration, @HibernateCore Session session)
>>    {
>>        configuration.add(AliasContribution.create(Session.class,
>> session));
>>    }
>>
>> Does anything break if it's not there?
>>
>> ---------------------------------------------------------------------
>> 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


Re: Using multiple databases?

Posted by Howard Lewis Ship <hl...@gmail.com>.
Yes, it's because of a 3rd party library that adds support for
HibernateSearch and it's FullTextSearchSession (which extends from
Session). https://issues.apache.org/jira/browse/TAPESTRY-2615

It should probably be switched to use ServiceOverride, as Alias is deprecated.

On Fri, Oct 22, 2010 at 4:42 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
> Can someone explain to me why the tapestry-hibernate module contributes to
> Alias?
>
> public static void contributeAlias(Configuration<AliasContribution>
> configuration, @HibernateCore Session session)
>    {
>        configuration.add(AliasContribution.create(Session.class,
> session));
>    }
>
> Does anything break if it's not there?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>



-- 
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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Can someone explain to me why the tapestry-hibernate module contributes to
Alias?

public static void contributeAlias(Configuration<AliasContribution>
configuration, @HibernateCore Session session)
    {
        configuration.add(AliasContribution.create(Session.class,
session));
    }

Does anything break if it's not there?

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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
If you do 

git clone git://hetdiana.homeip.net/tapestry5.git -b hibmod

you get the current version. I wouldn't consider it mature enough to merge
yet, I still need to fix breaking tapestry-core and other things because of
the modification to the ObjectLocator interface and tapestry-hibernate also
needs to be modified, but tapestry-hibernate-core seems to function well.
As soon as I'm confident that everything is mature (I still found a bug in
the ioc modifications) I'll reupload the patch to JIRA.

In the test suite you can find an example of how the system would work.

There are two packages, blue and red. Both have a Module class. Both have
an annotation (@Blue and @Red). Both have an example entity. By default, it
will use /hibernate-red.cfg.xml and /hibernate-blue.cfg.xml (for marker
@ThisIsALongMarker it would use /hibernate-thisIsALongMarker.cfg.xml)

The nice thing is that, as far as I can see, unless you do weird things
(override services and stuff like that), it is backwards compatible.

Feedback would be appreciated.

Tom.



On Wed, 20 Oct 2010 00:43:10 +0200, Tom van Dijk <to...@tvandijk.nl> wrote:
> Okay, I can't use that code review tool. Maybe it is because I use git 
> and the rest of the world (except Howard?) uses svn?
> 
> Anyway, you can pull from my git repository, it's conveniently located 
> downstairs in the living room.
> 
> git://hetdiana.homeip.net/tapestry5.git
> 
> I've created branch "iocmod1" and branch "iocmod2" and branch "iocmod3" 
> and branch "hibmod"
> 
> iocmod1 adds dynamic services
> iocmod2 adds dynamic contributions
> iocmod3 adds getService(serviceInterface, markers) to ObjectLocator 
> (what is better, Set<Class<? extends Annotation>> or Set<Class> ?)
> 
> hibmod is a work in progress, for the next couple of hours at least it 
> will contain my changes to tapestry-hibernate-core, without integration 
> testing.
> 
> If you pull branch iocmod3 you get all proposed changes to ioc core and 
> if you pull branch iocmod2 you get only those that don't appear to break

> test cases in tapestry-core and perhaps other projects
> 
> They are rebased upon the latest trunk (including Igor's change on 
> @Startup annotations).
> 
> I have yet to update the diff files in JIRA, I'll get to that later. 
> What is the best course of action? Change to using SVN and upload SVN 
> diff files? I kinda like git because it lets me do all the branching and

> merging with ease.
> 
> 
> 
> Op 19-10-2010 20:13, Tom van Dijk schreef:
>> I used the git from Howard. I'll check the code review  tool later
>> today/tomorrow.
>>
>> On Tue, 19 Oct 2010 08:51:19 -0700, Josh
Canfield<jo...@gmail.com>
>> wrote:
>>> I was trying to take a look at your patch but I couldn't get a good
>> merge.
>>> Are you synch'd to the trunk?
>>>
>>> I found the rietveld code review tool helpful (
>>> http://codereview.appspot.com/), would you consider putting your patch
>>> there
>>> so we can get a better look without having to download and install the
>>> patch? I've created a tapestry5 project there.
>>> On 19 Oct 2010 03:19, "Tom van Dijk"<to...@tvandijk.nl>  wrote:
>> ---------------------------------------------------------------------
>> 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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
  Okay, I can't use that code review tool. Maybe it is because I use git 
and the rest of the world (except Howard?) uses svn?

Anyway, you can pull from my git repository, it's conveniently located 
downstairs in the living room.

git://hetdiana.homeip.net/tapestry5.git

I've created branch "iocmod1" and branch "iocmod2" and branch "iocmod3" 
and branch "hibmod"

iocmod1 adds dynamic services
iocmod2 adds dynamic contributions
iocmod3 adds getService(serviceInterface, markers) to ObjectLocator 
(what is better, Set<Class<? extends Annotation>> or Set<Class> ?)

hibmod is a work in progress, for the next couple of hours at least it 
will contain my changes to tapestry-hibernate-core, without integration 
testing.

If you pull branch iocmod3 you get all proposed changes to ioc core and 
if you pull branch iocmod2 you get only those that don't appear to break 
test cases in tapestry-core and perhaps other projects

They are rebased upon the latest trunk (including Igor's change on 
@Startup annotations).

I have yet to update the diff files in JIRA, I'll get to that later. 
What is the best course of action? Change to using SVN and upload SVN 
diff files? I kinda like git because it lets me do all the branching and 
merging with ease.



Op 19-10-2010 20:13, Tom van Dijk schreef:
> I used the git from Howard. I'll check the code review  tool later
> today/tomorrow.
>
> On Tue, 19 Oct 2010 08:51:19 -0700, Josh Canfield<jo...@gmail.com>
> wrote:
>> I was trying to take a look at your patch but I couldn't get a good
> merge.
>> Are you synch'd to the trunk?
>>
>> I found the rietveld code review tool helpful (
>> http://codereview.appspot.com/), would you consider putting your patch
>> there
>> so we can get a better look without having to download and install the
>> patch? I've created a tapestry5 project there.
>> On 19 Oct 2010 03:19, "Tom van Dijk"<to...@tvandijk.nl>  wrote:
> ---------------------------------------------------------------------
> 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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
I used the git from Howard. I'll check the code review  tool later
today/tomorrow.

On Tue, 19 Oct 2010 08:51:19 -0700, Josh Canfield <jo...@gmail.com>
wrote:
> I was trying to take a look at your patch but I couldn't get a good
merge.
> Are you synch'd to the trunk?
> 
> I found the rietveld code review tool helpful (
> http://codereview.appspot.com/), would you consider putting your patch
> there
> so we can get a better look without having to download and install the
> patch? I've created a tapestry5 project there.
> On 19 Oct 2010 03:19, "Tom van Dijk" <to...@tvandijk.nl> wrote:

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


Re: Using multiple databases?

Posted by Josh Canfield <jo...@gmail.com>.
I was trying to take a look at your patch but I couldn't get a good merge.
Are you synch'd to the trunk?

I found the rietveld code review tool helpful (
http://codereview.appspot.com/), would you consider putting your patch there
so we can get a better look without having to download and install the
patch? I've created a tapestry5 project there.
On 19 Oct 2010 03:19, "Tom van Dijk" <to...@tvandijk.nl> wrote:

Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
  Op 19-10-2010 10:14, Massimo Lusetti schreef:
> On Mon, Oct 18, 2010 at 10:05 PM, Tom van Dijk<to...@tvandijk.nl>  wrote:
>
>> 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.
>>
> The idea sounds interesting as a solution for your question (hibernate
> multiple database).
> Please would you like to elaborate a little more? Where is the real
> evidence of dynamic? ...It's just dynamic in creation/construction
> time?
>
> Cheers
Yes, it is dynamic in construction time. Perhaps I should've named the 
thing "runtime services" instead of "dynamic services" now you mention it.

The idea is not something that allows further adding/removing of 
services after startup. It's just so that during startup extra services 
can be defined.
Right now I'm rewriting tapestry-hibernate as an example. (and already 
discovering I need an additional method in ObjectLocator, 
getServices(serviceInterface, markers))

Cheers too.

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


Re: Using multiple databases?

Posted by Massimo Lusetti <ml...@gmail.com>.
On Mon, Oct 18, 2010 at 10:05 PM, Tom van Dijk <to...@tvandijk.nl> wrote:

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

The idea sounds interesting as a solution for your question (hibernate
multiple database).
Please would you like to elaborate a little more? Where is the real
evidence of dynamic? ...It's just dynamic in creation/construction
time?

Cheers
-- 
Massimo
http://meridio.blogspot.com

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


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
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.

Tom.

On Sun, 17 Oct 2010 09:47:19 -0700, Howard Lewis Ship <hl...@gmail.com>
wrote:
> Patches needs to come through the JIRA system, for administrative
reasons.
> 
> On Sun, Oct 17, 2010 at 7:11 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
>> Okay, I got to work a bit and here's a patch that does what I
described.
>> 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 <to...@tvandijk.nl>
wrote:
>>> 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
of
>>> 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
modules,
>> 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
multiple
>>> 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
being
>>> initialized.
>>>
>>> I can imagine such a dynamic service builder work as follows. After
the
>>> "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
<hl...@gmail.com>
>>> 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
of
>>>> them (via marker annotations).
>>>>
>>>> On Sat, Oct 16, 2010 at 7:56 AM, Tom van Dijk <to...@tvandijk.nl>
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<to...@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
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: 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


Re: Using multiple databases?

Posted by Howard Lewis Ship <hl...@gmail.com>.
Patches needs to come through the JIRA system, for administrative reasons.

On Sun, Oct 17, 2010 at 7:11 AM, Tom van Dijk <to...@tvandijk.nl> wrote:
> Okay, I got to work a bit and here's a patch that does what I described.
> 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 <to...@tvandijk.nl> wrote:
>> 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 of
>> 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 modules,
> 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 multiple
>> 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 being
>> initialized.
>>
>> I can imagine such a dynamic service builder work as follows. After the
>> "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 <hl...@gmail.com>
>> 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 of
>>> them (via marker annotations).
>>>
>>> On Sat, Oct 16, 2010 at 7:56 AM, Tom van Dijk <to...@tvandijk.nl> 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<to...@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 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: 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
>



-- 
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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by Tom van Dijk <to...@tvandijk.nl>.
Okay, I got to work a bit and here's a patch that does what I described.
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 <to...@tvandijk.nl> wrote:
> 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 of
> 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 modules,
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 multiple
> 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 being
> initialized.
> 
> I can imagine such a dynamic service builder work as follows. After the
> "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 <hl...@gmail.com>
> 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 of
>> them (via marker annotations).
>> 
>> On Sat, Oct 16, 2010 at 7:56 AM, Tom van Dijk <to...@tvandijk.nl> 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<to...@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 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: 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

Re: Using multiple databases?

Posted by Tom van Dijk <to...@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 of
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 modules, 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 multiple
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 being
initialized.

I can imagine such a dynamic service builder work as follows. After the
"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 <hl...@gmail.com>
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 of
> them (via marker annotations).
> 
> On Sat, Oct 16, 2010 at 7:56 AM, Tom van Dijk <to...@tvandijk.nl> 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<to...@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 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: 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


Re: Using multiple databases?

Posted by Howard Lewis Ship <hl...@gmail.com>.
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 <to...@tvandijk.nl> 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<to...@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 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: 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
>
>



-- 
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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by Tom van Dijk <to...@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 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<to...@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 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: 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


Re: Using multiple databases?

Posted by Howard Lewis Ship <hl...@gmail.com>.
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 <to...@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 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: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>



-- 
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: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: Using multiple databases?

Posted by "Joost Schouten (ml)" <jo...@jsportal.com>.
Hi Tom,

I'm not completely sure I understand how you wish to accomplish this in 
detail, but the copier idea sounds dangerous to me.

We run a system where we have a different db per license (read client) 
and many clients on one webapp. In our architecture we have used spring 
in which all services are defined as prototypes and pass the 
HibernateSession with its connection properties as constructor argument 
to make sure one service can never switch db's. Some overhead in the 
fact we have a pool of services per db.

The services are managed by a context class (one per db/client). In 
Tapestry we have build a per thread ServiceProvider class. This service 
provider checks the HttpSession for the context the asking user belongs 
to and returns the required service from the correct db/context. This 
way our pages/components don't need to know anything about where the 
service comes from.

The downfall is that we can't directly @Inject all our services and have 
to go through the @Injecte'd ServiceProvider. Ok for us, but I'm sure 
its possible to overwrite Tapestries inject process to accomplish this.

Hope it is of some help.
Cheers,
Joost



Tom van Dijk 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: 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


Re: Using multiple databases?

Posted by Christophe Cordenier <ch...@gmail.com>.
Hi

To find elements on how to override some Tapestry Hibernate services, you
can have a look at http://github.com/spreadthesource/tapestry5-spring-tx

If you combine this with Howard's design advices, i guess you will have all
the elements to develop your solution.


2010/6/2 Tom van Dijk <to...@tvandijk.nl>

> 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: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org
>
>


-- 
Regards,
Christophe Cordenier.

Developer of wooki @wookicentral.com