Hi everyone,
First of all i am working with the session per request pattern. I also have an interceptor for logging purposes, that persists an event everytime i insert/update an object.
When i insert an object everything works fine, but when i get an object and try to make an update, im getting the following exception:
Code:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at com.elnominal.dao.ArticleDAO.makePersistent(ArticleDAO.java:257)
at com.elnominal.servlet.controller.InsertArticleServlet.service(InsertArticleServlet.java:72)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.elnominal.servlet.SearchDataFilter.doFilter(SearchDataFilter.java:54)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.elnominal.servlet.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:33)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.elnominal.servlet.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:104)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
I know that the problem is that i have two open sessions, because to make my interceptor work i had to create a new hibernate session.
This is the method where the exception is thrown:
Code:
public void makePersistent(Article article, AuditLogInterceptor interceptor) throws InfrastructureException {
Session newSession = HibernateUtil.getSessionFactory().openSession(interceptor);
interceptor.setSession(newSession);
Transaction tx = null;
try {
tx = newSession.beginTransaction();
newSession.saveOrUpdate(article);
tx.commit();
} catch (HibernateException ex) {
tx.rollback();
log.error("An error while making Article persistent has ocurred: ", ex);
throw new InfrastructureException(ex);
} finally {
newSession.close();
}
}
this is the servlet call to my makePersistent() method:
Code:
...
AuditLogInterceptor interceptor = new AuditLogInterceptor();
interceptor.setUserId(user.getId());
interceptor.setIpAddress(HttpServletUtils.getClientIpAdress(request));
interceptor.setUserAgent(HttpServletUtils.getRequestHeader(request, "user-agent"));
article.setUser(user);
articleDao.makePersistent(article, interceptor);
...
and this is my HibernateSessionRequestFilter (session per request pattern):
Code:
public class HibernateSessionRequestFilter implements Filter {
private static Logger log = Logger.getLogger(HibernateSessionRequestFilter.class);
private SessionFactory sf;
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
try {
sf.getCurrentSession().beginTransaction();
// Call the next filter (continue request processing)
chain.doFilter(request, response);
// Commit and cleanup
sf.getCurrentSession().getTransaction().commit();
} catch (StaleObjectStateException staleEx) {
log.error("An error while working with hibernate sessions has ocurred: ", staleEx);
throw staleEx;
} catch (Throwable ex) {
log.error("An error while working with hibernate sessions has ocurred: ", ex);
// Rollback only
ex.printStackTrace();
try {
if (sf.getCurrentSession().getTransaction().isActive()) {
sf.getCurrentSession().getTransaction().rollback();
}
} catch (Throwable rbEx) {
log.error("An error while working with hibernate sessions has ocurred: ", rbEx);
rbEx.printStackTrace();
}
// Let others handle it... maybe another interceptor for exceptions?
throw new ServletException(ex);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
sf = HibernateUtil.getSessionFactory();
}
public void destroy() {}
}
Can someone help me? i am really stuck at this,
Thanks in advance