sourceforge email appears broken. retrying...

-------- Original Message --------
Subject: Re: [Wicket-develop] RequestCycle bug?
Date: Mon, 25 Apr 2005 17:20:28 -0700
From: Jonathan Locke <[EMAIL PROTECTED]>
To: [email protected]
References: <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>




what about the problems that chris raised with clustering? does the change make any sense?

another thing is this: do we have to change the design or could we just provide hooks for this special thing? in fact, isn't it possible to work around this problem? when a request is going to cause a redirection, just don't close your hibernate session in onEndRequest(). set a boolean in your session that's effectively redirectionInProgress or whatever and then ignore onBeginRequest if this is true. finally, check in your onEndRequest and only if it's false, close the hibernate session. this keeps the very clean way things are designed and puts the burden for solving this special problem on some kind of session subclass that deals with hibernate requests (which is important to a hibernate solution anyway). am i making sense?

Eelco Hillenius wrote:

So, what do we do...
1. keep things the way they are, but document it better (Wiki) and maybe provide an easier way to acchieve the pattern I described earlier;
2. make WebRequestCycle so that it will allways span the whole 'logical' request, be that with or without a redirect.


Votes/ opinions please?

Eelco

Eelco Hillenius wrote:

Depends on what level you look at it. You could consider it a bug if you look at it from a high-level perspective. However, from a low-level perspective, they *are* two different requests, with at least their own instances of HttpServletRequest and HttpServletResponse. So, anyone depending on low-level stuff, would have a problem if we 'fixed' Wicket to use one request cycle instance for action/render requests.

Anyway, there is a not-too-difficult fix that users can implement themselves. This is an example:


Our custom session (note that it is also the factory for request cycle objects):


/**
* Custom session.
*/
public final class FmoDemoSession extends WebSession
{
/**
* temporary storage for our request cycle. To avoid problems with e.g. Hibernate
* (lazy collections) and to be able to logically handle the action- and render request
* as one, this variable is set by the request cycle when it regconizes (onEndRequest)
* that it is about to redirect. When this variable is set, the requestCycleFactory
* reuses the request cycle instead of creating a new one. This variable is reset by
* the request cycle when it regconizes that it is NOT about to redirect.
*/
WebRequestCycle redirectingRequestCycle;


/**
* factory for request cycles.
*/
private IRequestCycleFactory requestCycleFactory = new IRequestCycleFactory()
{
public RequestCycle newRequestCycle(Session session, Request request, Response response)
{
if(redirectingRequestCycle != null)
{
// we were redirecting... reuse the request cycle
redirectingRequestCycle.setRequest(request);
redirectingRequestCycle.setResponse(response);
return redirectingRequestCycle;
}


// we are not reusing; create a new request cycle
return new FmoDemoRequestCycle((WebSession)session, (WebRequest)request, response);
}
};


   /**
    * Construct.
    * @param application
    */
   public FmoDemoSession(FmoDemoApplication application)
   {
       super(application);
   }

   /**
    * @see wicket.Session#getRequestCycleFactory()
    */
   protected IRequestCycleFactory getRequestCycleFactory()
   {
       return requestCycleFactory;
   }
}

The custom request cycle.

/**
* Special request cycle for this application that opens and closes a hibernate session
* for each request.
*/
public final class FmoDemoRequestCycle extends WebRequestCycle
{
/**
* Logger.
*/
private static final Log log = LogFactory.getLog(FmoDemoRequestCycle.class);


   /**
    * De actieve hibernate sessie.
    */
   private transient Session hibernateSession = null;

/**
* Construct.
* @param session session object
* @param request request object
* @param response response object
*/
public FmoDemoRequestCycle(WebSession session, WebRequest request, Response response)
{
super(session, request, response);
}


/**
* @see wicket.RequestCycle#onBeginRequest()
*/
protected void onBeginRequest()
{
final SessionFactory factory = HibernateHelper.getSessionFactory();
hibernateSession = factory.openSession();
}


/**
* @see wicket.RequestCycle#onEndRequest()
*/
protected void onEndRequest()
{
if(getRedirect())
{
// we're about to redirect; don't close our session yet, as we might need
// it for e.g. lazy collections etc.
FmoDemoSession session = (FmoDemoSession)getSession();
session.redirectingRequestCycle = this;
}
else
{
HibernateHelper.closeQuietly(hibernateSession);
hibernateSession = null;
FmoDemoSession session = (FmoDemoSession)getSession();
session.redirectingRequestCycle = null;
}
}


   public Session getHibernateSession()
   {
       return hibernateSession;
   }
}

The application class that also is a Wicket session factory:

public class FmoDemoApplication extends WebApplication implements ISessionFactory
{
/**
* Constructor
*/
public FmoDemoApplication()
{
}


   /**
    * @see wicket.ISessionFactory#newSession()
    */
   public Session newSession()
   {
       return new FmoDemoSession(FmoDemoApplication.this);
   }

   /**
    * @see wicket.protocol.http.WebApplication#init()
    */
   public void init()
   {
       setSessionFactory(this);
   }
}


This pattern works. What do you think of it? Is it useable enough to put on the Wiki? Or maybe even build in more 'native' support for in Wicket?


Eelco


Martijn Dashorst wrote:

Gentlemen,

To my amazement, the request cycle doesn't work as expected: the processing of a request with a submit consists of the following RequestCycle calls:

RequestCycle.onBeginRequest()
   ... process page
   ... form.onSubmit()
   ... setResponsePage(...)
RequestCycle.onEndRequest()
redirect()!!!!!!!!!!!
RequestCycle.onBeginRequest()
   ... render page
RequestCycle.onEndRequest()

Where this goes wrong is when using the request cycle to store an open hibernate session, and supplying the response page /with/ that session. After the redirect, /that/ session is closed (as should be done in onEndRequest()). When the response page is rendered, it uses a stale hibernate session.

For the user this is strange: the redirect shouldn't split the requestcycle into two seperate cycles.

Does anybody have a different view than I?

Martijn




------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ Wicket-develop mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/wicket-develop




------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ Wicket-develop mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/wicket-develop

Reply via email to