Ideally, the User
object would have a method that returns a List<UnownedObject>
so that the callers get a clean API. One way to do that is for the User
object to have an instance of the DAO so it could ask the DAO to do the query.
In order to do this, the PersistenceManager
can't be closed until the end of the request. One way to do this is to create a servlet filter:
public class PersistenceManagerFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
request.setAttribute("pm", pm);
chain.doFilter(request, response);
} finally {
pm.close();
}
}
}
Then you can injected the PersistenceManager
into your DAO. If you use Guice you can do:
@RequestScoped
public class UserDao {
private final PersistenceManager pm;
@Inject
UserDao(PersistenceManager pm) {
this.pm = pm;
}
public User getUser(parameters) {
Key key = createKey(parameters);
User user = pm.getObjectById(User.class, key);
user.setUserDao(this);
return user;
}
}
This works best when UserDao
is in the same package as User
so User.setUserDao()
can be package scope. You could decide to set the PersistenceManager
into the User
object instead of the UserDao
.
Next you need to create a Guice module to bind PersistenceManager
:
public class PersistenceManagerModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides @RequestScoped
PersistenceManager providePersistenceManager(HttpServletRequest request) {
return (PersistenceManager) request.getAttribute("pm");
}
}
Finally you need to configure Google App Engine to use Guice.
This is just one possible way to do it. You could be more clever had have providePersistenceManager
create the PersistenceManager
and store it as a request attribute instead of having the servlet filter create the PersistenceManager
(the filter would still close it). You could also have the servlet filter get the Guice Injector so you can avoid using setAttribute()
and getAttribute()
and instead use a more type-safe API.