使用RequestFactory延迟加载

时间:2012-03-21 21:03:50

标签: gwt lazy-loading requestfactory

我正在使用带有Hibernate和RequestFactory的GWT 2.4,我有像这样的查询

contextA.getEntityById(id).with("elements").fire(new Receiver<EntityBaseProxy>() {
        @Override
        public void onSuccess(EntityBaseProxy entity) {
            System.out.println(entity.getElements().size());
  }
});

我有点困惑,当elements(实体的孩子)被懒散地取出时,我在System.out.println(entity.getElements().size());

中得到一个NullPointer

3 个答案:

答案 0 :(得分:1)

hibernate获取策略不应该对客户端中的结果产生影响。 RF-Servlet根据指定的with子句遍历服务的结果(实现getEntityById())。 看起来服务实现已经在getElements()或null实体中返回空列表。

答案 1 :(得分:1)

我没有使用hibernate,但我找到了一个优雅的解决方案,可以使用LAZY加载和RequestFactory。它使用ServletFilter并将请求包装到我的DAO服务器实现中。该实现创建了一个可用于整个请求的ThreadLocal EntityManager。请注意,您仍然需要在事务中包装合并。我能够删除所有try {} finally {em.close()}方法,并且不再加载EAGER。在requestContext中使用with()方法允许服务器端getter加载附加实体,因此您可以从客户端实现影响对象图加载。

这是我的过滤器

public class PersistenceFilter implements Filter {
    protected static final Logger logger = Logger.getLogger(PersistenceFilter.class.getName());

    private static final EntityManagerFactory factory = PersistenceManagerFactory.getEntityManagerFactory();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {
        PersistenceManager.setEntityManager(null);
        factory.close();
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        EntityManager em = factory.createEntityManager();

        PersistenceManager.setEntityManager(em);

        try {
            chain.doFilter(req, res);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (em.getTransaction().isActive()) {
                em.close();    
            }
        }
    }
}

<!-- Then simply add this to your web.xml -->
<filter-mapping>
  <filter-name>PersistenceFilter</filter-name>
  <url-pattern>/dao</url-pattern>
</filter-mapping>

答案 2 :(得分:0)

我的第一个解决方案:

  • 我在entity.getElements()
  • 上保留了延迟加载
  • 添加一个新的瞬态方法,用于从DOA获取元素,我们称之为getElementsFromBd()
  • 执行EntityProxy中getElementsFromBd()的映射
  • 在我的演示者中,我致电getElementsFromBd()而非getElementsFromBd()

演示者

contextA.getEntityById(id).with("elementsFromDb").fire(new Receiver<EntityBaseProxy>() {
    @Override
    public void onSuccess(EntityBaseProxy entity) {
        System.out.println(entity.getElementsFromBd().size());
}
});

实体模型

...
@Transient
public List<Element> getElementsFromDb(){
   doa.getElementsFromDb(this.id);
}
...

谢谢大家

修改

我最终使用了一个扩展RequestFactoryServlet的servlet,开始并提交事务

public class CustomRequestFactoryServlet extends RequestFactoryServlet {

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Transaction tx = null;
    try {
        Session session = HibernateUtil.getCurrentSession();
        tx = session.beginTransaction();
        super.service(request, response);
        session.getTransaction().commit();
    } finally {
        if (tx != null && tx.isActive()) {
            tx.rollback();
        }
    }
}

}