Hi, I'm currently developing an app in GAE/J using simple JSP+Servlet and JDO.
I'm trying to come up with a simple MVC-style pattern where a request will hit a servlet and the servlet will either forward() (via RequestDispatcher) the end result to a JSP or the response will sendRedirect() to another JSP page.
One of the thing I'd like to do is to get the JDO PersistenceManager in init() method and close the persistence manager on destroy() method. So here's roughly how it works:
- init() => initialize a persistence manager (from a factory) as a member variable of the current servlet
- doGet()/doPost() => perform query/processing then either forward or redirect to another servlet/jsp
- destroy() => close the persistence manager
The problem starts with the redirect/forward. It appears that if I do forward()/include() (via RequestDispatcher) or sendRedirect(), the destroy() method of the current servlet (that calls the method) will not be executed.
I read somewhere that forward() will not go back to the original Servlet while include() does. I did try both and they seem to behave the same.
If relying on destroy() to close a persistence manager is not a good idea then perhaps I should shift all the queries to the model? Let's say I have a simple model object called Model. If the queries are part of the object, perhaps I should do something like "getById()" in which the PersistenceManager is created and destroyed within that method.
Bear Bibeault wrote:destroy() is only called when the servlet is taken out of service, usually because the web app is shutting down.
Hm... this leads to more questions. I thought the way servlet works is as follow:
- Browser requests something to the web-app container
- The web-app container will create an instance of a servlet (or jsp)
- The web-app container will execute init(), service(), destroy()
- Then the instance of this servlet is garbage collected or something...
But what you're saying is that the instance of a servlet is only created once. The init() and service() methods are to be called when processing a new request from the client. But the destroy() will never be called unless the web-app is to be shut down (or maybe via some other ways).
- An instance of Servlet will only be created if there is no instance yet
- init() will only be called once, when the instance of the Servlet is created
- service() will be called when there's a new request coming from the client
- destroy() will only be called once too, as you mentioned it
So I guess the next question is: why RequestDispatcher.include() does not go back to the original servlet that calls the method? Could this be an implementation bug?
code might look like this:
- process stuff
- dispatcher.include(request, response);
- System.out.println("To see if this is being called");