0

I'am using GWT 2.4 with Hibernate and RequestFactory and I have queries like this one

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

I'am little confused, when elements, which are the children of the entity, are fetched lazily, I get a NullPointer in System.out.println(entity.getElements().size());

3 Answers 3

1

The hibernate fetch strategy shouldn't have an impact on the results in the client. The RF-Servlet traverses the result of the service (that implements getEntityById()) according to the specified with-clauses. Looks like the service implementation already returns a null list in getElements() or a null entity.

Sign up to request clarification or add additional context in comments.

2 Comments

BTW, when I use eager fetshing, it works. So I doubt that the implementation of the service is the source of the problem
Hm, maybe your Hibernate session is already closed at the time the RF servlet collects the data? You can take a look at Spring's OpenSessionInViewFilter for a possible solution.
1

I am not using hibernate but I have found an elegant solution that works with LAZY loading and RequestFactory. It uses a ServletFilter and wraps requests to my DAO server implementation. The implementation creates a ThreadLocal EntityManager that can be used for the entire request. Note you still have to wrap merge's in a transaction. I was able to remove all my try { } finally {em.close()} methods and no more EAGER loading. Using the with() methods in your requestContext allows the server side getters to load attached entities, so you can affect the object graph load from the client side implementation.

Here's my Filter

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>

Comments

0

My first solution :

  • I kept the Lazy loading on the entity.getElements()
  • Add a new transient methode that fetch the elements from the DOA, let call it getElementsFromBd()
  • Do the mapping for getElementsFromBd() in the EntityProxy
  • In my presenter I called getElementsFromBd()instead of getElementsFromBd()

Presenter

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

Entity model

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

Thanks everybody

EDIT

I ended up using a servlet that extends RequestFactoryServlet where I begin and commit the transactions

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();
        }
    }
}

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.