2009-08-03 129 views
2

我的问题更多的是关于如何实现与Google App Engine的无主关系的最佳实践问题。我使用JDO做我的坚持,并在谷歌文档喜欢推荐我坚持我的无主关系的列表,像这样:实现无主关系Google App Engine

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class User implements Serializable, UserDetails { 
... 

    @Persistent 
    private List<Key> groups; 
... 
} 

现在,我在我的困境来到时,我去查询使用该对象列表他们的关键对象。所以,当我得到我的组密钥列表,以便实际返回组对象列表时,我必须查看该密钥才能获取该对象。我的问题是对模型对象进行无主查询的推荐方式是什么?

我的模型对象上应该有一个PersistanceManagerFactory的实例,这样我可以进行查找吗?

我的模型对象上应该有一个我的GroupDAO对象的实例,所以我可以查找?

我应该有一个工具来做这种查找吗?

我是新来的,所以我只想知道哪个是最好的方法来做到这一点。谢谢。

回答

1

理想情况下,User对象将有一个返回List<UnownedObject>的方法,以便调用者可以获得干净的API。一种方法是让User对象具有DAO实例,以便它可以要求DAO执行查询。

为了做到这一点,PersistenceManager直到请求结束才能关闭。这样做的一个方法是创建一个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(); 
    } 
    } 
} 

然后你就可以注射PersistenceManager到你的DAO。如果你使用Guice你可以这样做:

@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; 
    } 
} 

这个工作最好时UserDao是在同一个包User所以User.setUserDao()可以包范围。您可以决定将PersistenceManager设置为User对象而不是UserDao

接下来,您需要创建一个吉斯模块绑定PersistenceManager

public class PersistenceManagerModule extends AbstractModule { 
    @Override 
    protected void configure() { 
    } 

    @Provides @RequestScoped 
    PersistenceManager providePersistenceManager(HttpServletRequest request) { 
    return (PersistenceManager) request.getAttribute("pm"); 
    } 
} 

最后,你需要配置Google App Engine to use Guice

这只是一种可能的方式来做到这一点。您可以更聪明地拥有providePersistenceManager创建PersistenceManager并将其存储为请求属性,而不是让servlet过滤器创建PersistenceManager(过滤器仍将关闭它)。您也可以让servlet过滤器获得Guice Injector,这样您就可以避免使用setAttribute()getAttribute(),而是使用更安全的API。

+0

如果你使用Guice的ServletModule,这更容易,因为你可以让Guice将PersistenceManager注入PersistenceManagerFilter,所以你不必使用request.getAttribute()。在这种情况下,PersistenceManagerModule只会调用PMF.get() – NamshubWriter 2009-08-07 00:46:47

1

Google recommends创建一个单例PersistenceManagerFactory。我不会在你的模型中粘贴PMF。

+0

是的,我说错了。我有一个工厂单身人士,我只是不知道最好是将键转换成实际组。如果我应该在拥有物体或DAO中做到这一点。 – nwallman 2009-08-03 03:28:37