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.