• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Illegal attempt to associate a collection with two open sessions

 
arushi tomar
Ranch Hand
Posts: 91
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am using Mysql database and eclipse. I don't understand where I am doing wrong. Trying to update mapping table through this:
My controller class: UpdateCustList.java

UpdateService.java


updateCust.jsp


and my complete error :

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:40)
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:268)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:217)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
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.engine.CascadingAction$5.cascade(CascadingAction.java:218)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:437)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:326)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:108)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
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.javaweb.service.UpdateService.update(UpdateService.java:22)
at com.javaweb.controller.UpdateCustList.doPost(UpdateCustList.java:54)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

Thanks in advance.
 
Dave Tolls
Ranch Hand
Posts: 2091
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have opened two sessions, one in the doPost and one in the update method.
In the first you get the List of Customers, which associates it to the first session, and in the second you are attempting to persist that in the second session.

You can't do that.

You should have only the one session.
 
arushi tomar
Ranch Hand
Posts: 91
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Resolved.

I created a static Session session in my HibernateUtil.java and doing this :

public static void openSession() {
setSession(sessionFactory.openSession());
}

public static Session getSession() {
return session;
}

public static void setSession(Session session) {
HibernateUtil.session = session;
}
}

then this wherever i needed a session :

HibernateUtil.openSession();
Session session = HibernateUtil.getSession();

 
Dave Tolls
Ranch Hand
Posts: 2091
15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That doesn't look terribly thread safe.
It looks to me like you would be sharing sessions between requests, which could cause all sorts of problems.
 
arushi tomar
Ranch Hand
Posts: 91
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What else can i do?
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
arushi tomar wrote:What else can i do?

The design of your application is completely wrong! And that's why you need to open two sessions. With a much better design you won't be experiencing the error you get.

Here is what you have to do:
  • The UpdateCustList servlet should only get the necessary info from the request object and pass it on to the user service. So from your code it seems you need the user id and a list of customer ids.
  • Not related to the issue but very important: a servlet should never write HTML, use a JSP only for the view.
  • Create a User business service (e.g. UserService interface and implementation class) with one method: updateCustomers. This method has two parameters: userId and a list of customerIds. In this method you can open a session retrieve the user, retrieve all customers, save the user in the end and close the session. All business logic can be done within the same transaction and commited or rollbacked when needed
  • Create some DAOs or Repositories for the necessary Crud operations on User and Customer (so you can reuse these methods in other business services as well)
  • And you'll probably need to use some contextual sessions as well


  • Did you consider using Spring for your application instead of trying to handle all transaction stuff yourself? Because as you have already experienced it's very hard to get it right. And when using a third-party library like Spring, you only need an annotation (and some config)

    Hope it helps!
    Kind regards,
    Roel
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic