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

Aaron Zeckoski aaronz at vt.edu
Fri Jan 22 09:09:58 PST 2010


That should not be an issue since we have extensive tests and I
followed the best practice for generating equals and hashcode (either
use the auto-generated ones or leave blank to allow hibernate to
generate them) but if you want to double check that you can. I think I
would do that after you exhaust other options.
-AZ


On Fri, Jan 22, 2010 at 5:01 PM, John Bush <john.bush at rsmart.com> wrote:
> 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"
>
>



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