[Building Sakai] Wrapping a method call in a Hibernate transaction/session?

Antranig Basman antranig.basman at colorado.edu
Thu Feb 11 08:49:36 PST 2010


On 11/02/2010 09:23, Jim Eng wrote:
> Hi Aaron,
>
> I'm back with another question about hibernate session management. The
> context is pretty much the same as the last two times I asked about
> this. I'm in a plain vanilla HttpServlet. I have available these EVALSYS
> singletons:
>
> - EvalEvaluationSetupService
> - EvalEvaluationService
> - EvalAuthoringService
>
> Each of these is accessed through its own
> "org.springframework.transaction.interceptor.TransactionProxyFactoryBean" with
> the injected value for "transactionManager" a reference to
> "org.sakaiproject.springframework.orm.hibernate.GlobalTransactionManager".
> I thought would mean that my calls to the EVALSYS component would be in
> hibernate session/transactions, but I am still getting errors when I try
> to save an entity that contains a reference to another existing entity.
> The exception says there is no hibernate session.
>
> I'm wondering whether I should be using the EvalDaoInvoker to wrap
> everything related to my attempt to save an entity. We do not want to
> rollback all "create" and "update" actions because one fails, which
> suggests we want transactions at the level of a particular entity.
> Suppose I have a method to extract an EvalItem from an XML element and
> save it. The method attempts to retrieve an existing EvalItem and update
> it. If none is found, the method creates a new EvalItem and attempts to
> save it. If the XML element provides an EID for an EvalScale, the method
> retrieves the EvalScale and adds it to the java object representing the
> EvalItem before saving the EvalItem. I think I need to wrap that entire
> process in a transaction. Does that make sense?
>
>  From your experience, does it seem like I might need to make explicit
> use of the EvalDaoInvoker to accomplish that? If so, is the way that's
> done in the inferDefaultViewParameters() method of the
> EvaluationVPInferrer class a good example of how it might be done?
>
> https://source.sakaiproject.org/contrib/evaluation/trunk/tool/src/java/org/sakaiproject/evaluation/tool/inferrers/EvaluationVPInferrer.java
>
>
> It's probably been a while since you've worked on this, so sorry to be
> pressing you for ideas. I hope some part of this might ring a bell that
> might help me. I've been digging through various docs related to
> Hibernate transactions and such, but in Sakai most of what we do with
> hibernate is several layers removed from the code I'm working on, so I'm
> not sure how to get any control over what I need to without upsetting
> other parts of the system.
>
> Suggestions welcome.
>
> Thanks.
>
> Jim

The method "invokeTransactionalAccess" which is provided at base by the 
GenericDAO system is the method to be used for this. As you can see in 
the VPInferrer, it accepts a Runnable which wraps the code which you 
want to be suitably contextualised by whatever it is the DAO applies (in 
this case, as you say, a Hibernate Session, Transaction, etc. and all 
the associated gubbins) without provoking a dependency on invisible 
classes. Just inject that bean and send your runnable into the 
"invokeRunnable" method. Here is the relevant section from the 
applicationContext.xml file of the tool:

     <!-- special wrapper beans which work with genericdao to allow 
hibernate lazy inits -->
     <bean id="org.sakaiproject.evaluation.ModelAccessWrapperInvoker"
 
class="org.sakaiproject.evaluation.tool.wrapper.ModelAccessWrapperInvoker">
         <property name="daoInvoker" 
ref="org.sakaiproject.evaluation.dao.EvalDaoInvoker" />
     </bean>


More information about the sakai-dev mailing list