You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by de...@gmx.de on 2012/11/26 15:26:42 UTC

TapestryCayenneModule - register listener on startup

Hi,

I'd like to register a listener and filter at application startup on a Cayenne data domain (a non-Tapestry filter/listener). I need to add something like these two lines somewhere:

runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(new LastModifiedListener());
runtime.getDataDomain().addFilter(new ChangeSetFilter());

Since I use tapestry5-cayenne there's no easy way to do this, because I just add the dependency in my pom and then inject the cayenne object context (or data context). I never do something like 
ServerRuntime runtime = new ServerRuntime("cayenne.xml"); ......

In the TapestryCayenneModule there's a ObjectContextProvider service with a private field runtime. I tried to override this service and add my two lines but got a conflict because in TapestryCayenneModule.java the service is not only bound but also overridden.

Then I tried to inject this service into my startup method and access the DataDomain object via the ObjectContext returned by a method of the service. But nothing worked. I guess it's too early, the service isn't available yet. The actual exception was 
Registry Error invoking service contribution method de.myapp.services.AppModule.registerCayenneFilterAndListener(): Unable to delegate method invocation to property 'request' of <Proxy 
for RequestGlobals(org.apache.tapestry5.services.RequestGlobals)>, because the property is null.

I also tried a method with @Startup and 
ServerRuntime runtime = new ServerRuntime("cayenne.xml"); ......
but then the data domain in the TapestryCayenneModule doesn't know about any listener or filter.


So is there any way to access a field of a service from another module on startup?
Or is there something like the @Startup annotation but at a later point of time, after the services are available?

Initially I asked on the cayenne mailing list 
http://mail-archives.apache.org/mod_mbox/cayenne-user/201211.mbox/%3C20121121200224.59850@gmx.net%3E
but then it became more of a tapestry question.


Cheers,
-bjello



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


Re: TapestryCayenneModule - register listener on startup

Posted by de...@gmx.de.
> 1) You didn't specify whether you're using the "server" or the "client"

tapestry5-cayenne-server, 0.5-SNAPSHOT

> sense that the Request is null.  But that suggests the problem is in your
> code because neither implementation of ObjectContextProvider references 
> the Request service.

You're absolutely right. Your comment made me realize I'd made a stupid mistake: I used currentContext() instead of newContext(). *facepalm*
Then I gave up too easily because I couldn't get the source code attached in the eclipse debugger and I thought my startup method couldn't work anyway because ObjectContextProvider isn't eager loaded.

> Can you post the full code of, eg, the registerCayenneFilterAndListener
> method?

This is the code with newContext() instead of currentContext() and it seems to work now :)

@Startup
public void registerCayenneFilterAndListener(@Inject ObjectContextProvider provider) {
    DataContext dataContext = (DataContext) provider.newContext();
    dataContext.getEntityResolver().getCallbackRegistry().addListener(new LastModifiedListener());
    dataContext.getParentDataDomain().addFilter(new ChangeSetFilter());
}

The @Inject isn't even necessary? 
This also works:
public void registerCayenneFilterAndListener(ObjectContextProvider provider) ...

Thank you for your comment.


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


Re: TapestryCayenneModule - register listener on startup

Posted by Robert Zeigler <ro...@roxanemy.com>.
A few notes.

1) You didn't specify whether you're using the "server" or the "client" t5-cayenne module. I will assume you are using the "server" module (since you mentioned DataContext).

2) The exception noted doesn't seem to be caused by t5cayenne code. It looks like it's a problem in your code.  The Request service is a "shadow" service. Basically, it's a wrapper around RequestGlobals that fetches the current value of "request" from the RequestGlobals service. In this case, RequestGlobals.getRequest() is returning null. That's because the request is being accessed during @Startup, which is /not/ during a request. So it makes sense that the Request is null.  But that suggests the problem is in your code because neither implementation of ObjectContextProvider references the Request service.

Can you post the full code of, eg, the registerCayenneFilterAndListener method?

In any event, exposing the Cayenne Runtime object as a Tapestry IOC service and injecting that service into the ObjectContextProvider implementations is probably a good idea, so I'll consider adding that to t5cayenne.

Robert

On Nov 26, 2012, at 11/268:26 AM , devnull2000@gmx.de wrote:

> Hi,
> 
> I'd like to register a listener and filter at application startup on a Cayenne data domain (a non-Tapestry filter/listener). I need to add something like these two lines somewhere:
> 
> runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(new LastModifiedListener());
> runtime.getDataDomain().addFilter(new ChangeSetFilter());
> 
> Since I use tapestry5-cayenne there's no easy way to do this, because I just add the dependency in my pom and then inject the cayenne object context (or data context). I never do something like 
> ServerRuntime runtime = new ServerRuntime("cayenne.xml"); ......
> 
> In the TapestryCayenneModule there's a ObjectContextProvider service with a private field runtime. I tried to override this service and add my two lines but got a conflict because in TapestryCayenneModule.java the service is not only bound but also overridden.
> 
> Then I tried to inject this service into my startup method and access the DataDomain object via the ObjectContext returned by a method of the service. But nothing worked. I guess it's too early, the service isn't available yet. The actual exception was 
> Registry Error invoking service contribution method de.myapp.services.AppModule.registerCayenneFilterAndListener(): Unable to delegate method invocation to property 'request' of <Proxy 
> for RequestGlobals(org.apache.tapestry5.services.RequestGlobals)>, because the property is null.
> 
> I also tried a method with @Startup and 
> ServerRuntime runtime = new ServerRuntime("cayenne.xml"); ......
> but then the data domain in the TapestryCayenneModule doesn't know about any listener or filter.
> 
> 
> So is there any way to access a field of a service from another module on startup?
> Or is there something like the @Startup annotation but at a later point of time, after the services are available?
> 
> Initially I asked on the cayenne mailing list 
> http://mail-archives.apache.org/mod_mbox/cayenne-user/201211.mbox/%3C20121121200224.59850@gmx.net%3E
> but then it became more of a tapestry question.
> 
> 
> Cheers,
> -bjello
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


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