Re: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-21 Thread Sam Gendler

I suppose Spring's transaction management would start a second
transaction after rolling back the first one, but ONLY if you call a
second service method that is wrapped in a transaction after getting
an exception in a prior one.  Generally, my code is written such that
a listener will probably only call a single service method directly,
and any others will be called from inside the first, so the
transaction that surrounds the first method will be inherited by any
methods that are called from within it.  However, Spring's transaction
manager will most definitely leave the session open after a
transaction has been rolled back, which allows any lazily loaded
objects to be loaded from the session during the rendering phase.  I
can't guarantee it isn't a problem, but we've never had any issues
with it, so I suspect the warning against reusing a rolledback session
is related to writing objects baxck to the db, not simply reading
them.  Regardless, if you always catch the exception and go to an
error page, you'll never need to worry about lazily loading objects
after the excpetion causes a rollback, and that's about 98% of our
cases.

--sam

On 6/20/07, Michael Sims [EMAIL PROTECTED] wrote:

Sam wrote:
 In my case, I'm using Spring's transaction management code to inject,
 via AOP, transaction semantics around service method calls.  This
 means that my transaction commits when the service method (called from
 the listener, almost always) returns, so I can catch any exceptions
 before I even start rendering a response.  In the vast majority of
 cases, if I get an error, I'm going to show an error page, so
 accessing objects that may cause lazy loading after the exception and
 rollback really isn't a problem, but I will say that in the few
 instances where it does occur, it doesn't appear to be a problem,
 precisely because anything involving lazy loading while rendering the
 view is guaranteed to be a read-only operation.

So, Spring's transaction management does in fact start a second transaction on 
the
same session, even after an exception has been thrown, and you haven't seen an 
issue
from this?  I think I'm going to go this route too, and only worry about it if a
problem comes up.  If it does, I'll just make sure to eager fetch everything I 
might
need on a listener method that might throw an expected exception, before the 
first
transaction is committed, and then I'll just close the session rather that 
start a
second transaction.

 So in our case, we don't have to explicitly handle a transaction
 manager, cause Spring is automatically injecting the start and commit
 of each transaction, as appropriate, and that is all defined in a
 config file rather than in code.

That's very cool.  At this point in time the explicit calls to manage the
transactions aren't bothering me, although I will probably refactor them out in 
the
future.  I haven't gotten into AOP just yet and I'm not ready to introduce 
another
complication, but it's definitely on my to-do list.

Thanks...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-21 Thread Michael Sims
Sam wrote:
 I suppose Spring's transaction management would start a second
 transaction after rolling back the first one, but ONLY if you call a
 second service method that is wrapped in a transaction after getting
 an exception in a prior one.  Generally, my code is written such that
 a listener will probably only call a single service method directly,
 and any others will be called from inside the first, so the
 transaction that surrounds the first method will be inherited by any
 methods that are called from within it.  However, Spring's transaction
 manager will most definitely leave the session open after a
 transaction has been rolled back, which allows any lazily loaded
 objects to be loaded from the session during the rendering phase.

Thanks for the info.  Just to nitpick, if you're accessing lazily loaded 
objects,
you actually are starting a second transaction, just not explicitly.  Your 
database
driver must be in auto-commit mode if that works.  This is explicit in the 
Hibernate
reference manual (section 11.1.1), and also is mentioned on
http://www.hibernate.org/43.html under Can I commit the transaction before
rendering the view?.

My only point is that you'll get a second transaction if a service method is 
called
OR if a not-yet-initialized collection or property is accessed in your view.  If
you're in auto-commit mode you may be more than just two, depending on how many 
lazy
properties are fetched.

 I
 can't guarantee it isn't a problem, but we've never had any issues
 with it, so I suspect the warning against reusing a rolledback session
 is related to writing objects baxck to the db, not simply reading
 them.

Yes, that's what I'm hoping.  I suppose I will find out soon. ;)  Thanks...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Steve Shucker
I just realized I had a bug relating to this yesterday and I could use a 
little help solving it.  I think the solution is to force the hibernate 
session to flush before the response is committed, but I'm not sure 
how/where to inject that call into tapestry.  If I knew where to make 
tapestry call my code, getting hibernate to flush is easy.


I just spent a few minutes this morning trying to explicitly call 
response.sendError, but once the WebRequestServicer has called its 
service method, the response is committed so I get an IllegalStateException.


In general, I think we should either use an open session in view or DAO 
approach, not a hybrid.  The point of open session in view is that 
developers don't have to worry about transactional contexts, 
reenlistment and stuff like that.  If you're throwing those gains away 
with separate request/response or listener/other transactions, you're 
better off letting DAOs manage transactions and getting the benefits of 
their narrower scope and cleaner definition of where transactions start 
and stop.


Even if spring says it's ok to start a new transaction in a session 
where the previous transaction was rolled back, I think it's a bad 
idea.  I use open session in view, which is one transaction per session 
in its entire lifetime.  For daemon processes, a session will go through 
multiple transactions, but the moment something goes wrong, I start with 
a new session.


-Steve

Michael Sims wrote:

Sorry again for the not 100% Tapestry related question, but I got such helpful
responses from my last question, and it's clear that there are a lot of people 
on
this list that have already solved these issues that I'm running into (and I'm
getting jack from the Hibernate forums ;) )...

I've implemented the open session in view pattern in my Tapestry application 
in
the fairly conventional way. I inject a threaded Session via Hivemind using a
service factory, and the service factory activates a transaction and creates a
ThreadCleanupListener to commit() the transaction and close the session when the
thread is done processing the user's request.  So far so good.

What I'm not sure how to do is handle situations where I may need to inform the 
user
that their transaction failed.  For example, let's say I have a typical CRUD
application to create new users for my system, and I want to be able to 
correctly
handle the scenario where an administrator attempts to create a new user with a 
name
that is already in use (a primary or unique key violation). I can't simply let 
the
ThreadCleanupListener handle the commit() in this case; if I do this, and an
exception is thrown, it is too late to inform the user since the request has 
already
been rendered.

The Open Session in View page on the Hibernate web site [1] states that a good
approach is to use two transactions in one Session.  If I took this approach, I
would attempt to commit the transaction in my listener method, and catch the
exception thrown from the database, and convert this into a validation error 
which
states that the username is already taken.

The problem with this is that the Hibernate documentation is quite clear that 
if any
exception occurs, the transaction should be rolled back, and the Session should 
be
closed and discarded.  Rolling back is not a problem, but if I close and 
discard the
Session, I'm no longer using open session in view.  I'll have to go to the 
trouble
to initialize any lazy collections or proxies that the view might need before I
attempt the commit, otherwise I'll get a LazyInitializationException.

But I've read one of the Spring guys saying [2] that it's ok to begin a new
transaction on the same Session that has been rolled back, if you're only using 
it
to initialize lazy collections.  This would be nice if it were actually true; it
would simplify things for me quite a bit.  But I hestitate to rely on that, 
since
the Hibernate documentation says otherwise.

Can someone with a bit more experience with give me some advice on how to 
approach
this?  Thanks in advance...

[1] http://www.hibernate.org/43.html
[2] http://forum.springframework.org/showpost.php?p=29579postcount=6


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

  


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Michael Sims
Steve Shucker wrote:
 I just realized I had a bug relating to this yesterday and I could
 use a little help solving it.  I think the solution is to force the
 hibernate session to flush before the response is committed, but I'm
 not sure how/where to inject that call into tapestry.  If I knew
 where to make tapestry call my code, getting hibernate to flush is
 easy.

If I need to commit or rollback the transaction in a listener method (or 
elsewhere),
I inject a thread-bound transaction manager service into my pages.  The 
transaction
manager has the request-wide session injected into it, and I call methods on the
manager to commit, rollback, etc.  I got this idea from Tapestry 5's
tapestry-hibernate project:

http://tinyurl.com/3b3dok

In my implementation, I have split out the ThreadCleanupListener 
responsibilities
into another object, but the rest is pretty much the same.

Does this help at all?

 In general, I think we should either use an open session in view or
 DAO approach, not a hybrid.  The point of open session in view is that
 developers don't have to worry about transactional contexts,
 reenlistment and stuff like that.  If you're throwing those gains away
 with separate request/response or listener/other transactions, you're
 better off letting DAOs manage transactions and getting the benefits
 of their narrower scope and cleaner definition of where transactions
 start
 and stop.

The issue with that, in my case anyway, is that I'm using a SqueezeAdaptor to
transparently squeeze a Hibernate persisted object into class + id, and then
unsqueeze to the full entity on the next request.  I do this for client 
persistence
and direct link parameters, etc., to keep my objects from being serialized into 
the
query string.  My SqueezeAdaptor has to have an active session and transaction, 
and
this occurs before any listener methods are called.  I could have the
SqueezeAdaptor, or anything else that needs to use Hibernate, start and finish 
their
own transactions via DAO calls, but this would result in a high number of
transactions per request, so I don't think that would be worth anything.

Worse still, if any of those transactions results in an error, you are supposed 
to
close the Session, which detaches all persistent objects and makes it 
impossible to
access lazily-initialized properties.

 Even if spring says it's ok to start a new transaction in a session
 where the previous transaction was rolled back, I think it's a bad
 idea.  I use open session in view, which is one transaction per
 session
 in its entire lifetime.

Yes, but what about my scenario with the CRUD application?  An administrator 
tries
to persist a new user, and there is a primary key violation, but using open 
session
in view, you don't know this until the response has already been rendered, and 
by
then it's too late to present an error.  So, how do you handle this without
comitting the transaction early, before the response has been rendered?


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Steve Shucker
Keep in mind the difference between a flush and a commit in hibernate.  
A flush executes all the queued sql against the database without 
committing the transaction.  Hibernate does this whenever it has changes 
that needed to be sent to the database before a query is run.  
Otherwise, it defers the flush until just before the commit.  Unless 
you're using deferred constraints in oracle, constraint violations and 
other db-related exceptions will be raised during the flush, not the commit.


What I'd really like to do is configure something in hivemind that would 
run just before tapestry commits the response.  Then I could call 
session.flush() there to force the exception before the response is 
committed.  I just don't know how I can accomplish this.


-Steve

Michael Sims wrote:

Steve Shucker wrote:
  

I just realized I had a bug relating to this yesterday and I could
use a little help solving it.  I think the solution is to force the
hibernate session to flush before the response is committed, but I'm
not sure how/where to inject that call into tapestry.  If I knew
where to make tapestry call my code, getting hibernate to flush is
easy.



If I need to commit or rollback the transaction in a listener method (or 
elsewhere),
I inject a thread-bound transaction manager service into my pages.  The 
transaction
manager has the request-wide session injected into it, and I call methods on the
manager to commit, rollback, etc.  I got this idea from Tapestry 5's
tapestry-hibernate project:

http://tinyurl.com/3b3dok

In my implementation, I have split out the ThreadCleanupListener 
responsibilities
into another object, but the rest is pretty much the same.

Does this help at all?

  

In general, I think we should either use an open session in view or
DAO approach, not a hybrid.  The point of open session in view is that
developers don't have to worry about transactional contexts,
reenlistment and stuff like that.  If you're throwing those gains away
with separate request/response or listener/other transactions, you're
better off letting DAOs manage transactions and getting the benefits
of their narrower scope and cleaner definition of where transactions
start
and stop.



The issue with that, in my case anyway, is that I'm using a SqueezeAdaptor to
transparently squeeze a Hibernate persisted object into class + id, and then
unsqueeze to the full entity on the next request.  I do this for client 
persistence
and direct link parameters, etc., to keep my objects from being serialized into 
the
query string.  My SqueezeAdaptor has to have an active session and transaction, 
and
this occurs before any listener methods are called.  I could have the
SqueezeAdaptor, or anything else that needs to use Hibernate, start and finish 
their
own transactions via DAO calls, but this would result in a high number of
transactions per request, so I don't think that would be worth anything.

Worse still, if any of those transactions results in an error, you are supposed 
to
close the Session, which detaches all persistent objects and makes it 
impossible to
access lazily-initialized properties.

  

Even if spring says it's ok to start a new transaction in a session
where the previous transaction was rolled back, I think it's a bad
idea.  I use open session in view, which is one transaction per
session
in its entire lifetime.



Yes, but what about my scenario with the CRUD application?  An administrator 
tries
to persist a new user, and there is a primary key violation, but using open 
session
in view, you don't know this until the response has already been rendered, and 
by
then it's too late to present an error.  So, how do you handle this without
comitting the transaction early, before the response has been rendered?


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

  


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Michael Sims
Steve Shucker wrote:
 Keep in mind the difference between a flush and a commit in hibernate.
 A flush executes all the queued sql against the database without
 committing the transaction.  Hibernate does this whenever it has
 changes that needed to be sent to the database before a query is run.
 Otherwise, it defers the flush until just before the commit.  Unless
 you're using deferred constraints in oracle, constraint violations and
 other db-related exceptions will be raised during the flush, not the
 commit.

 What I'd really like to do is configure something in hivemind that
 would run just before tapestry commits the response.  Then I could
 call session.flush() there to force the exception before the response
 is committed.  I just don't know how I can accomplish this.

Ah, ok.  Sorry about that, I guess I need to learn to be a bit more precise in 
my
interpretation of the terms.  Still, a session manager service would allow 
you to
expose a method to flush() in a listener, yes?  Or you want to make this more
transparent/automatic so you can just redirect to a static error page on any
exception without having to explicitly flush()?

That still doesn't help for my particular use case though... I need to catch the
error and still render a response that might need to access lazily-initialized
properties of Hibernate persisted objects...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Steve Shucker
I'm really fishing for a hivemind guru to tell me how to inject some 
code in the tail end of the WebRequestServicer.service() method.  That 
would allow me to implement a general solution of flushing before the 
response is committed and forcing the exception to occur at a point 
where I can still notify the user.  I want things to be automatic rather 
than having to explicitly call Session.flush() in every listener 
method.  (If I was going to do that, I'd use an aspect.)


I know this doesn't quite solve your problem because you want to use 
another session to render your error response.  I'd consider a dedicated 
session in pageBeginRender of my error page (with some extra error 
handling) to set up the state for your error page.


-Steve

Michael Sims wrote:

Steve Shucker wrote:
  

Keep in mind the difference between a flush and a commit in hibernate.
A flush executes all the queued sql against the database without
committing the transaction.  Hibernate does this whenever it has
changes that needed to be sent to the database before a query is run.
Otherwise, it defers the flush until just before the commit.  Unless
you're using deferred constraints in oracle, constraint violations and
other db-related exceptions will be raised during the flush, not the
commit.

What I'd really like to do is configure something in hivemind that
would run just before tapestry commits the response.  Then I could
call session.flush() there to force the exception before the response
is committed.  I just don't know how I can accomplish this.



Ah, ok.  Sorry about that, I guess I need to learn to be a bit more precise in 
my
interpretation of the terms.  Still, a session manager service would allow 
you to
expose a method to flush() in a listener, yes?  Or you want to make this more
transparent/automatic so you can just redirect to a static error page on any
exception without having to explicitly flush()?

That still doesn't help for my particular use case though... I need to catch the
error and still render a response that might need to access lazily-initialized
properties of Hibernate persisted objects...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

  


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Michael Sims
Steve Shucker wrote:
 I'm really fishing for a hivemind guru to tell me how to inject some
 code in the tail end of the WebRequestServicer.service() method.

Looks like something similar was discussed here:

http://www.mail-archive.com/[EMAIL PROTECTED]/msg00316.html

Howard mentioned a possible feature addition to support this, and the original
poster said that he would add a JIRA issue, but I wasn't able to locate it if 
it was
ever added.

This would come in handy for something unrelated... I'm implementing your
WebRequestServicerFilter that handles synchronization for non-asset requests, 
but
your code doesn't detect asset requests if friendly URLs (AssetEncoder) are 
enabled.
I tried my best to find a way to leverage Tapestry's existing code to determine
which service was scheduled for a particular request, but the only thing that 
can
determine that is the IRequestCycle, and this isn't available in a
WebRequestServicerFilter.  I had to resort to code similar to yours that 
handles the
scheme AssetEncoder uses, but this code is fragile; if a new encoding method is
employed the filter will not be able to detect asset requests.  Oh well, for 
now the
kludge will have to do, I suppose.

 I'd consider a
 dedicated session in pageBeginRender of my error page (with some
 extra error handling) to set up the state for your error page.

Thanks, but that won't work for two reasons: (1) I don't have an error page as 
such,
many pages may need to handle these types of constraint violations, and 
sometimes
only when certain listeners are called, and (2) that would require me to 
basically
have two copies of all my persistent objects, one copy for each session.  I'd 
rather
manually eager fetch everything that my template is going to need before 
attempting
the commit than to do that...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Steve Shucker
Unless I'm really screwing up, my check works with friendly URLs.  I'm 
using them.  They way I understand the pipeline is that service encoders 
take the original http request and do some preprocessing before you end 
up with a WebRequest.  Look at RequestCycleFactoryImpl and AssetEncoder 
to see where this happens.  The short version is that the WebRequest 
should have a parameter set that identifies the tapestry service being 
called.


Thanks for the link.

-Steve

Michael Sims wrote:

Steve Shucker wrote:
  

I'm really fishing for a hivemind guru to tell me how to inject some
code in the tail end of the WebRequestServicer.service() method.



Looks like something similar was discussed here:

http://www.mail-archive.com/[EMAIL PROTECTED]/msg00316.html

Howard mentioned a possible feature addition to support this, and the original
poster said that he would add a JIRA issue, but I wasn't able to locate it if 
it was
ever added.

This would come in handy for something unrelated... I'm implementing your
WebRequestServicerFilter that handles synchronization for non-asset requests, 
but
your code doesn't detect asset requests if friendly URLs (AssetEncoder) are 
enabled.
I tried my best to find a way to leverage Tapestry's existing code to determine
which service was scheduled for a particular request, but the only thing that 
can
determine that is the IRequestCycle, and this isn't available in a
WebRequestServicerFilter.  I had to resort to code similar to yours that 
handles the
scheme AssetEncoder uses, but this code is fragile; if a new encoding method is
employed the filter will not be able to detect asset requests.  Oh well, for 
now the
kludge will have to do, I suppose.

  

I'd consider a
dedicated session in pageBeginRender of my error page (with some
extra error handling) to set up the state for your error page.



Thanks, but that won't work for two reasons: (1) I don't have an error page as 
such,
many pages may need to handle these types of constraint violations, and 
sometimes
only when certain listeners are called, and (2) that would require me to 
basically
have two copies of all my persistent objects, one copy for each session.  I'd 
rather
manually eager fetch everything that my template is going to need before 
attempting
the commit than to do that...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

  


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Michael Sims
Steve Shucker wrote:
 Unless I'm really screwing up, my check works with friendly URLs.  I'm
 using them.  They way I understand the pipeline is that service
 encoders take the original http request and do some preprocessing
 before you end up with a WebRequest.  Look at RequestCycleFactoryImpl
 and AssetEncoder to see where this happens.  The short version is
 that the WebRequest should have a parameter set that identifies the
 tapestry service being called.

What version of Tapestry?  In 4.0.2, the pipeline calls the
WebRequestServicerFilter's before the RequestCycleFactory and the encoders have 
done
their work.  With friendly URLs, a typical path for an asset is something like:

/assets/031a6b16419c47ad157a817021baa2d6/class/path/file

This is still the form it is in when it hits the filter.  getParameterNames()
returns an empty list, getParameterValue(ServiceConstants.SERVICE) returns null.
I'm currently using the following to recognize an asset request:

/assets.equals(request.getActivationPath())

You can verify this in the debugger by setting a breakpoint in both the filter 
and
line 81 of RequestCycleFactoryImpl (where decodeParameters() is called), and 
then
issuing a request for an asset.  The filter will be reached first.

The problem with this too, is that it's not immediately obvious that something 
is
wrong.  The filter will still do its job, namely synchronizing the requests, 
but it
will do it unnecessarily in the case of the asset requests.

If you're on a different version where things have changed, please disregard.


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Steve Shucker
You're right and now I feel stupid.  I'm actually using tapestry 4.1.1, 
but I fired up the debugger to  double check.  Sure enough, it was 
applying my filter to asset requests.  I could swear this worked at one 
point.  Anyway, I had the code lying around to decode manually (needed 
it in a regular servlet filter once), so here's a version that works:


   private ServiceEncoder[] serviceEncoders;
  
   public void service(WebRequest request, WebResponse response, 
WebRequestServicer servicer)

   throws IOException {
   // don't filter asset requests
   ServiceEncodingImpl encoding = new 
ServiceEncodingImpl(request.getActivationPath(),request.getPathInfo(),extractParameters(request));

   for(ServiceEncoder serviceEncoder: serviceEncoders){
   serviceEncoder.decode(encoding);
   if(encoding.isModified()){
   break;
   }
   }
   if 
(Tapestry.ASSET_SERVICE.equals(encoding.getParameterValue(ServiceConstants.SERVICE))) 
{

   servicer.service(request, response);
   } else {
   filterRequest(request, response, servicer);
   }
   }
  
   // copied from somewhere in tapestry

   private QueryParameterMap extractParameters(WebRequest request) {
   QueryParameterMap result = new QueryParameterMap();
   Iterator i = request.getParameterNames().iterator();
   while (i.hasNext()) {
   String name = (String) i.next();
   String[] values = request.getParameterValues(name);
   if (values.length == 1) {
   result.setParameterValue(name, values[0]);
   } else {
   result.setParameterValues(name, values);
   }
   }
   return result;
   }

Here's the hivemind config to inject the encoders:

  construct 
class=com.vms.infrastructure.websession.TapestrySessionTxFilter
  set-object property=serviceEncoders 
value=service-property:tapestry.url.LinkFactory:serviceEncoders/

   /construct

Thanks for catching my bug!

-Steve


Michael Sims wrote:

Steve Shucker wrote:
  

Unless I'm really screwing up, my check works with friendly URLs.  I'm
using them.  They way I understand the pipeline is that service
encoders take the original http request and do some preprocessing
before you end up with a WebRequest.  Look at RequestCycleFactoryImpl
and AssetEncoder to see where this happens.  The short version is
that the WebRequest should have a parameter set that identifies the
tapestry service being called.



What version of Tapestry?  In 4.0.2, the pipeline calls the
WebRequestServicerFilter's before the RequestCycleFactory and the encoders have 
done
their work.  With friendly URLs, a typical path for an asset is something like:

/assets/031a6b16419c47ad157a817021baa2d6/class/path/file

This is still the form it is in when it hits the filter.  getParameterNames()
returns an empty list, getParameterValue(ServiceConstants.SERVICE) returns null.
I'm currently using the following to recognize an asset request:

/assets.equals(request.getActivationPath())

You can verify this in the debugger by setting a breakpoint in both the filter 
and
line 81 of RequestCycleFactoryImpl (where decodeParameters() is called), and 
then
issuing a request for an asset.  The filter will be reached first.

The problem with this too, is that it's not immediately obvious that something 
is
wrong.  The filter will still do its job, namely synchronizing the requests, 
but it
will do it unnecessarily in the case of the asset requests.

If you're on a different version where things have changed, please disregard.


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

  


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Michael Sims
Steve Shucker wrote:
 You're right and now I feel stupid.

It's an easy mistake to make, I think.  Especially if it used to work and 
something
in the internals of Tapestry changed at some point.  I didn't mention it before
because I just assumed you weren't using friendly URLs...

 (needed it in a regular servlet filter once), so here's a version
 that works:

Nice, I'll use that, thanks.  That's better than my hack, for sure...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Sam Gendler

In my case, I'm using Spring's transaction management code to inject,
via AOP, transaction semantics around service method calls.  This
means that my transaction commits when the service method (called from
the listener, almost always) returns, so I can catch any exceptions
before I even start rendering a response.  In the vast majority of
cases, if I get an error, I'm going to show an error page, so
accessing objects that may cause lazy loading after the exception and
rollback really isn't a problem, but I will say that in the few
instances where it does occur, it doesn't appear to be a problem,
precisely because anything involving lazy loading while rendering the
view is guaranteed to be a read-only operation.

So in our case, we don't have to explicitly handle a transaction
manager, cause Spring is automatically injecting the start and commit
of each transaction, as appropriate, and that is all defined in a
config file rather than in code.  There's almost certainly a way to
use the classes provided by spring to do that work from within
hiveming without actually using the spring aplpication context itself,
if you don't want to eal with yet another IoC container\, and the
mechanism works really well, allowing your application code to be
completely independent of transaction semantics.  To the listener
method that makes the service call, it just looks like an exception
was thrown in the service call if the transaction commit fails, and
you can handle that case from within the listener pretty trivially.

--sam

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: Help with handling exceptions while using Hibernate's open-session-in-view pattern in Tapestry

2007-06-20 Thread Michael Sims
Sam wrote:
 In my case, I'm using Spring's transaction management code to inject,
 via AOP, transaction semantics around service method calls.  This
 means that my transaction commits when the service method (called from
 the listener, almost always) returns, so I can catch any exceptions
 before I even start rendering a response.  In the vast majority of
 cases, if I get an error, I'm going to show an error page, so
 accessing objects that may cause lazy loading after the exception and
 rollback really isn't a problem, but I will say that in the few
 instances where it does occur, it doesn't appear to be a problem,
 precisely because anything involving lazy loading while rendering the
 view is guaranteed to be a read-only operation.

So, Spring's transaction management does in fact start a second transaction on 
the
same session, even after an exception has been thrown, and you haven't seen an 
issue
from this?  I think I'm going to go this route too, and only worry about it if a
problem comes up.  If it does, I'll just make sure to eager fetch everything I 
might
need on a listener method that might throw an expected exception, before the 
first
transaction is committed, and then I'll just close the session rather that 
start a
second transaction.

 So in our case, we don't have to explicitly handle a transaction
 manager, cause Spring is automatically injecting the start and commit
 of each transaction, as appropriate, and that is all defined in a
 config file rather than in code.

That's very cool.  At this point in time the explicit calls to manage the
transactions aren't bothering me, although I will probably refactor them out in 
the
future.  I haven't gotten into AOP just yet and I'm not ready to introduce 
another
complication, but it's definitely on my to-do list.

Thanks...


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]