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

Jim Eng jimeng at umich.edu
Fri Jan 22 07:19:45 PST 2010


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
>
>



More information about the evaluation mailing list