[Contrib: Evaluation System] Help with DB transactions when using AuthoringService API

John Bush john.bush at rsmart.com
Fri Jan 22 09:01:04 PST 2010


another thing to check is how you implement equals and hashcode, getting those right can avoid a lot of hibernate issues, see https://www.hibernate.org/109.html

On Jan 22, 2010, at 8:19 AM, Jim Eng wrote:

> I am using XStream to deserialize the XML.  XStream creates an  
> EvalItem object with the EID set appropriately and all the properties  
> set appropriately.  The id of that EvalItem is null.
> 
> Once the servlet validates the properties in the new EvalItem object,  
> we try to retrieve an EvalItem with the same EID.  If that's null, we  
> save the new one that was created by XStream.  That works fine.  If  
> it's not null, we systematically copy property values from the new  
> item into the one that was retrieved from the AuthoringService, and  
> then we save that one.
> 
> Is it possible that something in XStream might be interacting with  
> hibernate?  Do you think the constructor for an EvalItem cause any  
> hibernate activity?
> 
> I'll try to go deeper.
> 
> Thanks.
> 
> Jim
> 
> 
> On Jan 22, 2010, at 10:07 AM, Aaron Zeckoski wrote:
> 
>> When I have encountered this in the past it normally required me to
>> find the place where something else was loading the same object
>> earlier in the hibernate session (so part of the same request
>> normally). It is likely to not be loaded directly and is probably
>> getting loaded by some other method or possibly even by a hibernate
>> lazy load. This is one of the worst hibernate problems to debug and
>> usually ends up requiring lots and lots of tracing and commenting
>> things out to figure out.
>> In this case, I am wondering if maybe you are actually creating an
>> item and setting the ID or EID to something that already exists. If
>> you are doing that then you are going to have a problem. Make sure
>> that if the item already exists you are loading it and then updating
>> that object rather than creating your own object and trying to update
>> it that way. You cannot update the data using a new object if you
>> already loaded it in the session and it is generally a better practice
>> to load existing objects and update them for hibernate (in my
>> experience).
>> Sorry I can't provide anything more directly useful.
>> -AZ
>> 
>> 
>> On Fri, Jan 22, 2010 at 2:48 PM, Jim Eng <jimeng at umich.edu> wrote:
>>> Hi Aaron,
>>> 
>>> I am trying to make calls to the AuthoringService from a servlet  
>>> that reads
>>> XML from a file and attempts to create various types of EVALSYS  
>>> entities.
>>> The servlet reads a file that defines an EvalScale and several  
>>> EvalItem
>>> entities.  The EvalScale (with eid of '1') is created (or updated  
>>> if the
>>> file is read again) with no problem.  Then the servlet reads the  
>>> XML for the
>>> first EvalItem. After deserializing the XML into an EvalItem object  
>>> named
>>> "newItem" and doing some validation and fix-up, the new item is  
>>> saved or
>>> updated, as follows:
>>> 
>>>       EvalItem item =
>>> this.getAuthoringService().getItemByEid(newItem.getEid());  // <---  
>>> line 404
>>>       if(item == null) {
>>>           //save new item
>>>               item = newItem;
>>>           event = EVENT_ITEM_SAVE;
>>>       } else {
>>>           //update existing
>>>           setProperties(item, newItem);
>>>           event = EVENT_ITEM_UPDATE;
>>>       }
>>> 
>>>       //save or update
>>>       this.getAuthoringService().saveItem(item,  
>>> currentUserId);  // <---
>>> line 417
>>> 
>>> Similar code works just fine for creating or updating an EvalScale,  
>>> but an
>>> exception is thrown when we try to update the EvalItem:
>>> 
>>> org.springframework.orm.hibernate3.HibernateSystemException: a  
>>> different
>>> object with the same identifier value was already associated with the
>>> session: [org.sakaiproject.evaluation.model.EvalItem#68]; nested  
>>> exception
>>> is org.hibernate.NonUniqueObjectException: a different object with  
>>> the same
>>> identifier value was already associated with the session:
>>> [org.sakaiproject.evaluation.model.EvalItem#68]
>>> 
>>> There's a stack trace at the end of the message.
>>> 
>>> It seems like the exception message says that we have retrieved the  
>>> EvalItem
>>> entity with id of 68 and now we're trying to save a different java  
>>> object
>>> with the id 68 in the same session.  When debugging, the java object
>>> retrieved in line 404 is object 27538 and has an id of 68.  When we  
>>> attempt
>>> to save it in line 417, it is the same object (27538) and has the  
>>> same id
>>> (68).
>>> 
>>> Any suggestions about what might be going on here?
>>> 
>>> One thing is that the EvalItem has a reference to an EvalScale.   
>>> Part of the
>>> fix-up is to get the EID of the EvalScale from the XML, retrieve the
>>> EvalScale that has that EID and add it to the EvalItem by a call to
>>> EvalItem.setScale(EvalScale scale).  I've seen that work in code  
>>> that does
>>> not have the problem I'm having.
>>> 
>>> Thanks.
>>> 
>>> Jim
>>> 
>>> 
>>> 
>>> 
>>> 2010-01-22 09:27:58,507  WARN http-8080-Processor24
>>> org.sakaiproject.evalport.servlet.EvalExchangeServlet - EvalItem  
>>> with eid
>>> '1' was not saved/updated in the database
>>> org.springframework.orm.hibernate3.HibernateSystemException: a  
>>> different
>>> object with the same identifier value was already associated with the
>>> session: [org.sakaiproject.evaluation.model.EvalItem#68]; nested  
>>> exception
>>> is org.hibernate.NonUniqueObjectException: a different object with  
>>> the same
>>> identifier value was already associated with the session:
>>> [org.sakaiproject.evaluation.model.EvalItem#68]
>>> Caused by:
>>> org.hibernate.NonUniqueObjectException: a different object with the  
>>> same
>>> identifier value was already associated with the session:
>>> [org.sakaiproject.evaluation.model.EvalItem#68]
>>>       at
>>> org 
>>> .hibernate 
>>> .engine 
>>> .StatefulPersistenceContext 
>>> .checkUniqueness(StatefulPersistenceContext.java:590)
>>>       at
>>> org 
>>> .hibernate 
>>> .event 
>>> .def 
>>> .DefaultSaveOrUpdateEventListener 
>>> .performUpdate(DefaultSaveOrUpdateEventListener.java:284)
>>>       at
>>> org 
>>> .hibernate 
>>> .event 
>>> .def 
>>> .DefaultSaveOrUpdateEventListener 
>>> .entityIsDetached(DefaultSaveOrUpdateEventListener.java:223)
>>>       at
>>> org 
>>> .hibernate 
>>> .event 
>>> .def 
>>> .DefaultUpdateEventListener 
>>> .performSaveOrUpdate(DefaultUpdateEventListener.java:33)
>>>       at
>>> org 
>>> .hibernate 
>>> .event 
>>> .def 
>>> .DefaultSaveOrUpdateEventListener 
>>> .onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
>>>       at  
>>> org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:564)
>>>       at org.hibernate.impl.SessionImpl.update(SessionImpl.java:552)
>>>       at org.hibernate.impl.SessionImpl.update(SessionImpl.java:544)
>>>       at
>>> org.springframework.orm.hibernate3.HibernateTemplate 
>>> $14.doInHibernate(HibernateTemplate.java:657)
>>>       at
>>> org 
>>> .springframework 
>>> .orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372)
>>>       at
>>> org 
>>> .springframework 
>>> .orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:654)
>>>       at
>>> org 
>>> .springframework 
>>> .orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:650)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .genericdao 
>>> .hibernate.HibernateGenericDao.baseUpdate(HibernateGenericDao.java: 
>>> 360)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .genericdao 
>>> .hibernate.HibernateGenericDao.update(HibernateGenericDao.java:650)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .genericdao 
>>> .hibernate.HibernateGenericDao.save(HibernateGenericDao.java:670)
>>>       at sun.reflect.GeneratedMethodAccessor505.invoke(Unknown  
>>> Source)
>>>       at
>>> sun 
>>> .reflect 
>>> .DelegatingMethodAccessorImpl 
>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>       at java.lang.reflect.Method.invoke(Method.java:592)
>>>       at
>>> org 
>>> .springframework 
>>> .aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java: 
>>> 296)
>>>       at
>>> org 
>>> .springframework 
>>> .aop 
>>> .framework 
>>> .ReflectiveMethodInvocation 
>>> .invokeJoinpoint(ReflectiveMethodInvocation.java:177)
>>>       at
>>> org 
>>> .springframework 
>>> .aop 
>>> .framework 
>>> .ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java: 
>>> 144)
>>>       at
>>> org 
>>> .springframework 
>>> .transaction 
>>> .interceptor 
>>> .TransactionInterceptor.invoke(TransactionInterceptor.java:107)
>>>       at
>>> org 
>>> .springframework 
>>> .aop 
>>> .framework 
>>> .ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java: 
>>> 166)
>>>       at
>>> org 
>>> .springframework 
>>> .aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
>>>       at $Proxy8.save(Unknown Source)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .evaluation 
>>> .logic 
>>> .EvalAuthoringServiceImpl 
>>> .saveItem_aroundBody28(EvalAuthoringServiceImpl.java:436)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .evaluation 
>>> .logic 
>>> .EvalAuthoringServiceImpl 
>>> .saveItem_aroundBody29$advice(EvalAuthoringServiceImpl.java:84)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .evaluation 
>>> .logic 
>>> .EvalAuthoringServiceImpl.saveItem(EvalAuthoringServiceImpl.java:1)
>>>       at sun.reflect.GeneratedMethodAccessor507.invoke(Unknown  
>>> Source)
>>>       at
>>> sun 
>>> .reflect 
>>> .DelegatingMethodAccessorImpl 
>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>       at java.lang.reflect.Method.invoke(Method.java:592)
>>>       at
>>> org 
>>> .springframework 
>>> .aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java: 
>>> 296)
>>>       at
>>> org 
>>> .springframework 
>>> .aop 
>>> .framework 
>>> .ReflectiveMethodInvocation 
>>> .invokeJoinpoint(ReflectiveMethodInvocation.java:177)
>>>       at
>>> org 
>>> .springframework 
>>> .aop 
>>> .framework 
>>> .ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java: 
>>> 144)
>>>       at
>>> org 
>>> .springframework 
>>> .transaction 
>>> .interceptor 
>>> .TransactionInterceptor.invoke(TransactionInterceptor.java:107)
>>>       at
>>> org 
>>> .springframework 
>>> .aop 
>>> .framework 
>>> .ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java: 
>>> 166)
>>>       at
>>> org 
>>> .springframework 
>>> .aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
>>>       at $Proxy18.saveItem(Unknown Source)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .evalport 
>>> .servlet 
>>> .EvalExchangeServlet.saveOrUpdateItems(EvalExchangeServlet.java:417)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .evalport 
>>> .servlet.EvalExchangeServlet.process(EvalExchangeServlet.java:215)
>>>       at
>>> org 
>>> .sakaiproject 
>>> .evalport 
>>> .servlet.EvalExchangeServlet.doPost(EvalExchangeServlet.java:186)
>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java: 
>>> 710)
>>>       at javax.servlet.http.HttpServlet.service(HttpServlet.java: 
>>> 803)
>>>       at
>>> org 
>>> .apache 
>>> .catalina 
>>> .core 
>>> .ApplicationFilterChain 
>>> .internalDoFilter(ApplicationFilterChain.java:269)
>>>       at
>>> org 
>>> .apache 
>>> .catalina 
>>> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java: 
>>> 188)
>>>       at
>>> org.sakaiproject.util.RequestFilter.doFilter(RequestFilter.java:616)
>>>       at
>>> org 
>>> .apache 
>>> .catalina 
>>> .core 
>>> .ApplicationFilterChain 
>>> .internalDoFilter(ApplicationFilterChain.java:215)
>>>       at
>>> org 
>>> .apache 
>>> .catalina 
>>> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java: 
>>> 188)
>>>       at
>>> org 
>>> .apache 
>>> .catalina 
>>> .core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
>>>       at
>>> org 
>>> .apache 
>>> .catalina 
>>> .core.StandardContextValve.invoke(StandardContextValve.java:174)
>>>       at
>>> org 
>>> .apache 
>>> .catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
>>>       at
>>> org 
>>> .apache 
>>> .catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
>>>       at
>>> org 
>>> .apache 
>>> .catalina.core.StandardEngineValve.invoke(StandardEngineValve.java: 
>>> 108)
>>>       at
>>> org 
>>> .apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java: 
>>> 151)
>>>       at
>>> org 
>>> .apache.coyote.http11.Http11Processor.process(Http11Processor.java: 
>>> 874)
>>>       at
>>> org.apache.coyote.http11.Http11BaseProtocol 
>>> $Http11ConnectionHandler.processConnection(Http11BaseProtocol.java: 
>>> 665)
>>>       at
>>> org 
>>> .apache 
>>> .tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java: 
>>> 528)
>>>       at
>>> org 
>>> .apache 
>>> .tomcat 
>>> .util 
>>> .net 
>>> .LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
>>>       at
>>> org.apache.tomcat.util.threads.ThreadPool 
>>> $ControlRunnable.run(ThreadPool.java:689)
>>>       at java.lang.Thread.run(Thread.java:613)
>>> 
>>> 
>>> 
>>> 
>> 
>> 
>> 
>> -- 
>> Aaron Zeckoski (azeckoski (at) vt.edu)
>> Senior Research Engineer - CARET - University of Cambridge
>> https://twitter.com/azeckoski - http://www.linkedin.com/in/azeckoski
>> http://aaronz-sakai.blogspot.com/ - http://tinyurl.com/azprofile
>> 
>> 
> 
> _______________________________________________
> evaluation mailing list
> evaluation at collab.sakaiproject.org
> http://collab.sakaiproject.org/mailman/listinfo/evaluation
> 
> TO UNSUBSCRIBE: send email to evaluation-unsubscribe at collab.sakaiproject.org with a subject of "unsubscribe"



More information about the evaluation mailing list