Hello,

I'm using Restlet above a JPA persistence layer with Hibernate as provider. 
That works reasonably well, but unfortunately I haven't found a way to 
handle the persistence sessions properly.

What I would like to see is that a new session is opened whenever needed and 
is closed after all request processing is done. This is my current attempt:

public class EntityManagerFilter extends Filter implements 
EntityManagerSource {

    private final EntityManagerFactory emf;
    private final ThreadLocal<EntityManager> entityManagerTL = new 
ThreadLocal<EntityManager>();

    public EntityManagerFilter(Context context, Restlet next, 
EntityManagerFactory emf) {
        super(context, next);
        this.emf = emf;
    }

    public EntityManagerFilter(Context context, EntityManagerFactory emf) {
        super(context);
        this.emf = emf;
    }

    public EntityManagerFilter(EntityManagerFactory emf) {
        this.emf = emf;
    }

    public EntityManager getEntityManager() {
        // we lazily initialize in case the entity manager is not actually 
needed
        // by a request
        EntityManager entityManager = entityManagerTL.get();
        if(entityManager == null) {
            entityManager = emf.createEntityManager();
            entityManagerTL.set(entityManager);
        }
        return entityManager;
    }

    @Override
    protected void afterHandle(Request request, Response response) {
        EntityManager entityManager = entityManagerTL.get();
        if(entityManager!=null) {
            entityManagerTL.remove();
            assert entityManager.isOpen():
                "Entity manager should only be closed here but must have 
been closed elsewhere";
            entityManager.close();
        }
        super.afterHandle(request, response);
    }
}

This filter is attached as the root of the application, forwarding to the 
router that does the main dispatch.

The approach works to some extent, but with a huge "but": most of the time I 
produce TemplateRepresentations to render data with Freemarker. The 
processing of those templates happens after the afterHandle(..) method of 
the filter, which means that the session is closed and if the template uses 
anything that is not eagerly fetched and the Java code hasn't used it will 
get an exception from the persistence layer. That is actually a pretty 
common case since a lot of the details of objects is needed only in the 
template rendering.

Currently I work around that problem by explicitly loading objects in Java 
code. I'd rather solve that problem properly, but I can't find a hook that 
gets called after the write(..) method of the representations. Long intro, 
short question: Is there such thing?

Thanks,
   Peter

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=1182479

Reply via email to