[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