RE: Managing a JPA/Hibernate session
Hi Could anyone give me some advice how I could implement such a Filter or ConnectorService for hibernate? The main problem is: How can I get the EntityManager that I created in the Filter at some other point? Now I'm using auto-generated JPA Controller classes form NetBeans but this leads to lots of problems when accessing data when the EntityManager has already been closed. Thanks for any Help Matt -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1730594
RE: Managing a JPA/Hibernate session
Hi Matt, There has been a recent discussion on this topic in this list. Some changes were made in SVN trunk so that ConnectorService callback methods are systematically called after sending representations/responses. You basically have to provide a custom ConnectorService that intercepts those calls to update your EntityManager accordingly. Also, as this piece of code seems rather generic, there might be an opportunity to provide a specific Restlet extension for this... Feel free to contribute one or to enter a RFE. Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : webp...@tigris.org [mailto:webp...@tigris.org] Envoyé : mercredi 15 avril 2009 19:50 À : discuss@restlet.tigris.org Objet : RE: Managing a JPA/Hibernate session Hi Could anyone give me some advice how I could implement such a Filter or ConnectorService for hibernate? The main problem is: How can I get the EntityManager that I created in the Filter at some other point? Now I'm using auto-generated JPA Controller classes form NetBeans but this leads to lots of problems when accessing data when the EntityManager has already been closed. Thanks for any Help Matt -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=17305 94 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1742765
RE: Re: Managing a JPA/Hibernate session
Hi Paul, You made a good point regarding the afterSend and beforeSend method. So, I decided to change their behavior. Those methods are now invoked all the time, even if there is no entity sent (null will be passed). Changes in SVN trunk. Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : blackh...@collab.net [mailto:blackh...@collab.net] Envoyé : jeudi 26 février 2009 17:31 À : discuss@restlet.tigris.org Objet : RE: Re: Managing a JPA/Hibernate session I have been looking more into the issue and have found some more additional issues. 1. As you suggested filters do not work as they are completed before the response is sent to the client. 2. The ConnectorService also does not work as the afterSend method is only called if there was an entity and there were no IO exceptions in streaming the result to the client. The result of this that you will have dangling EntityManagers as they are not closed. What is required is an interceptor/filter which can wrap the entire call to the restlet chain which wraps the handle and commit calls. This would allow you to do setup before the restlet calls and cleanup after the response has been committed. The developer then can include a finally block so that the cleanup is also performed after any exceptions. Paul -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=12337 13 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1278438
Re: Managing a JPA/Hibernate session
Jerome, Thanks, did you add it in a finally block so that it always gets executed even if there is an exception. Paul On 6-Mar-09, at 10:36 AM, Jerome Louvel wrote: Hi Paul, You made a good point regarding the afterSend and beforeSend method. So, I decided to change their behavior. Those methods are now invoked all the time, even if there is no entity sent (null will be passed). Changes in SVN trunk. Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : blackh...@collab.net [mailto:blackh...@collab.net] Envoyé : jeudi 26 février 2009 17:31 À : discuss@restlet.tigris.org Objet : RE: Re: Managing a JPA/Hibernate session I have been looking more into the issue and have found some more additional issues. 1. As you suggested filters do not work as they are completed before the response is sent to the client. 2. The ConnectorService also does not work as the afterSend method is only called if there was an entity and there were no IO exceptions in streaming the result to the client. The result of this that you will have dangling EntityManagers as they are not closed. What is required is an interceptor/filter which can wrap the entire call to the restlet chain which wraps the handle and commit calls. This would allow you to do setup before the restlet calls and cleanup after the response has been committed. The developer then can include a finally block so that the cleanup is also performed after any exceptions. Paul -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=12337 13 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1278438 Paul Austin President/CEO Revolution Systems Inc. +1 (604) 288-4304 x201 www.revolsys.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1278453
RE: Managing a JPA/Hibernate session
Paul, Yes I did! :) Cheers, Jerome -Message d'origine- De : Paul Austin [mailto:paul.aus...@revolsys.com] Envoyé : vendredi 6 mars 2009 19:41 À : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Jerome, Thanks, did you add it in a finally block so that it always gets executed even if there is an exception. Paul On 6-Mar-09, at 10:36 AM, Jerome Louvel wrote: Hi Paul, You made a good point regarding the afterSend and beforeSend method. So, I decided to change their behavior. Those methods are now invoked all the time, even if there is no entity sent (null will be passed). Changes in SVN trunk. Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : blackh...@collab.net [mailto:blackh...@collab.net] Envoyé : jeudi 26 février 2009 17:31 À : discuss@restlet.tigris.org Objet : RE: Re: Managing a JPA/Hibernate session I have been looking more into the issue and have found some more additional issues. 1. As you suggested filters do not work as they are completed before the response is sent to the client. 2. The ConnectorService also does not work as the afterSend method is only called if there was an entity and there were no IO exceptions in streaming the result to the client. The result of this that you will have dangling EntityManagers as they are not closed. What is required is an interceptor/filter which can wrap the entire call to the restlet chain which wraps the handle and commit calls. This would allow you to do setup before the restlet calls and cleanup after the response has been committed. The developer then can include a finally block so that the cleanup is also performed after any exceptions. Paul -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId =12337 13 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId =1278438 Paul Austin President/CEO Revolution Systems Inc. +1 (604) 288-4304 x201 www.revolsys.com -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=12784 53 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1278478
RE: Re: Managing a JPA/Hibernate session
I have been looking more into the issue and have found some more additional issues. 1. As you suggested filters do not work as they are completed before the response is sent to the client. 2. The ConnectorService also does not work as the afterSend method is only called if there was an entity and there were no IO exceptions in streaming the result to the client. The result of this that you will have dangling EntityManagers as they are not closed. What is required is an interceptor/filter which can wrap the entire call to the restlet chain which wraps the handle and commit calls. This would allow you to do setup before the restlet calls and cleanup after the response has been committed. The developer then can include a finally block so that the cleanup is also performed after any exceptions. Paul -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1233713
Re: Managing a JPA/Hibernate session
Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - http://trac.sarugo.org/restlet-jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: 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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); 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=4447dsMessageId=1182479 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1185212
RE: Managing a JPA/Hibernate session
Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - http://trac.sarugo.org/restlet-jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: 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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); 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=4447dsMessageId=1182479 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1185212 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1186386
Re: Managing a JPA/Hibernate session
Below is my solution which is based on a similar ServletFilter from the SpringFramework. You will need to set the entityManagerFactory before using this. I normall have that configured in spring and get a reference to this filter bean from the context. package com.revolsys.restlet; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceException; import org.apache.log4j.Logger; import org.restlet.Filter; import org.restlet.data.Request; import org.restlet.data.Response; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.EntityManagerHolder; import org.springframework.transaction.support.TransactionSynchronizationManager; public class OpenEntityManagerFilter extends Filter { private static final Logger logger = Logger.getLogger(OpenEntityManagerFilter.class); private EntityManagerFactory entityManagerFactory; protected int beforeHandle(Request request, Response response) { if (TransactionSynchronizationManager.hasResource(entityManagerFactory)) { request.getAttributes().put(this.toString(), Boolean.TRUE); } else { logger.debug(Opening JPA EntityManager in OpenEntityManagerFilter); try { EntityManager em = entityManagerFactory.createEntityManager(); TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(em)); } catch (PersistenceException ex) { throw new DataAccessResourceFailureException( Could not create JPA EntityManager, ex); } } return super.beforeHandle(request, response); } protected void afterHandle(Request request, Response response) { MapString, Object attributes = request.getAttributes(); if (attributes.get(this.toString()) != Boolean.TRUE) { EntityManagerHolder emHolder = (EntityManagerHolder)TransactionSynchronizationManager.unbindResource(entityManagerFactory); logger.debug(Closing JPA EntityManager in OpenEntityManagerFilter); EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager()); } } public EntityManagerFactory getEntityManagerFactory() { return entityManagerFactory; } public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } } On Wed, Feb 18, 2009 at 6:45 AM, Jerome Louvel jerome.lou...@noelios.comwrote: Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Representhttp://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend%28org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - http://trac.sarugo.org/restlet-jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: 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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); 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
Re: Managing a JPA/Hibernate session
Thanks Jerome! That will be a much neater solution. On Thu, Feb 19, 2009 at 1:15 AM, Jerome Louvel jerome.lou...@noelios.com wrote: Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - http://trac.sarugo.org/restlet-jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: 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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); 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=4447dsMessageId=1182479 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1185212 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1186386 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1188600
Re: Managing a JPA/Hibernate session
Paul, correct me if I am wrong, but I believe your solution suffers from the same problem as mine: if there is still data to fetch during the processing of a representation object (as it happens on the write(..) method of the TemplateRepresentation of the Freemarker extension), then you will get exceptions from the persistence layer. By using the ConnectorService the JPA sessions lives long enough to include the call to the write(..) method. Peter Paul Austin wrote: Below is my solution which is based on a similar ServletFilter from the SpringFramework. You will need to set the entityManagerFactory before using this. I normall have that configured in spring and get a reference to this filter bean from the context. package com.revolsys.restlet; import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceException; import org.apache.log4j.Logger; import org.restlet.Filter; import org.restlet.data.Request; import org.restlet.data.Response; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.EntityManagerHolder; import org.springframework.transaction.support.TransactionSynchronizationManager; public class OpenEntityManagerFilter extends Filter { private static final Logger logger = Logger.getLogger(OpenEntityManagerFilter.class); private EntityManagerFactory entityManagerFactory; protected int beforeHandle(Request request, Response response) { if (TransactionSynchronizationManager.hasResource(entityManagerFactory)) { request.getAttributes().put(this.toString(), Boolean.TRUE); } else { logger.debug(Opening JPA EntityManager in OpenEntityManagerFilter); try { EntityManager em = entityManagerFactory.createEntityManager(); TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(em)); } catch (PersistenceException ex) { throw new DataAccessResourceFailureException( Could not create JPA EntityManager, ex); } } return super.beforeHandle(request, response); } protected void afterHandle(Request request, Response response) { MapString, Object attributes = request.getAttributes(); if (attributes.get(this.toString()) != Boolean.TRUE) { EntityManagerHolder emHolder = (EntityManagerHolder)TransactionSynchronizationManager.unbindResource(entityManagerFactory); logger.debug(Closing JPA EntityManager in OpenEntityManagerFilter); EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager()); } } public EntityManagerFactory getEntityManagerFactory() { return entityManagerFactory; } public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } } On Wed, Feb 18, 2009 at 6:45 AM, Jerome Louvel jerome.lou...@noelios.comwrote: Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Representhttp://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend%28org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - http://trac.sarugo.org/restlet- jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: 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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); public EntityManagerFilter(Context context, Restlet
RE: Managing a JPA/Hibernate session
Thanks Jerome, that was what I was looking for. I just replaced the type and the afterHandle with afterSend and it seems all works as I wanted. For the record: it gets attached on the Application instance via setConnectorService(..) -- didn't take too long to find, but it might be a good addition for the JavaDoc of that class ;-) Cheers, Peter Jerome Louvel wrote: Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - [http://trac.sarugo.org/restlet- jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: 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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); 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=4447dsMessageId=1182479 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1185212 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1186386 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1189311
RE: Managing a JPA/Hibernate session
Hi Peter, I've updated the Javadocs as suggested! Cheers, Jerome -Message d'origine- De : news [mailto:n...@ger.gmane.org] De la part de Peter Becker Envoye : jeudi 19 fevrier 2009 02:47 A : discuss@restlet.tigris.org Objet : RE: Managing a JPA/Hibernate session Thanks Jerome, that was what I was looking for. I just replaced the type and the afterHandle with afterSend and it seems all works as I wanted. For the record: it gets attached on the Application instance via setConnectorService(..) -- didn't take too long to find, but it might be a good addition for the JavaDoc of that class ;-) Cheers, Peter Jerome Louvel wrote: Hi guys, This is such a hook available. See the ConnectorService#afterSend method: http://www.restlet.org/documentation/snapshot/api/org/restlet/service/ConnectorService.html#afterSend(org.restlet.resource.Represent ation) Hope this helps! Best regards, Jerome Louvel -- Restlet ~ Founder and Lead developer ~ http://www.restlet.org Noelios Technologies ~ Co-founder ~ http://www.noelios.com -Message d'origine- De : Michael Terrington [mailto:mich...@terrington.id.au] Envoye : mercredi 18 fevrier 2009 12:23 A : discuss@restlet.tigris.org Objet : Re: Managing a JPA/Hibernate session Hi Peter, I recently encountered this problem myself. I ended up creating a Representation wrapper that would close my EM after the call to write. The code [1] is part of restlet-jpa [2]. Regards, Michael. [1] - [http://trac.sarugo.org/restlet- jpa/browser/trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java [2] - http://trac.sarugo.org/restlet-jpa/ On Wed, Feb 18, 2009 at 10:22 AM, Peter Becker pbec...@itee.uq.edu.au wrote: 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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); 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=4447dsMessageId=1182479 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1185212 -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1186386 -- http://restlet.tigris.org/ds
Managing a JPA/Hibernate session
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 ThreadLocalEntityManager entityManagerTL = new ThreadLocalEntityManager(); 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=4447dsMessageId=1182479