繁体   English   中英

在上一个事务失败后,hibernate / spring尝试插入而不是保存(db中的记录已存在)

[英]hibernate/spring is trying to insert rather than save (record already exists in db) after the previous transaction failed

我有一个批处理接口类,它创建一个休眠会话,如下所示:

Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));

然后,它调用服务以从DB中获取对象列表,并在批处理类中遍历该列表,并对每个对象进行服务调用以对该对象进行一些处理。

在第二个对象上说,某个地方发生了一些nullpointerexception异常,而我在批处理类中捕获了该异常。 然后我尝试通过调用HibernateDaoSupport.getSession(false).save(object)处理第三个对象并在服务中尝试保存该对象-它实际上试图插入它(并且我得到一个错误,因为已经有一条记录了存在),而不是对其进行更新。

仅当前一个对象失败时,才会发生这种情况。 如果发生异常,它会在该Hibernate会话中执行某些操作吗? 有什么想法吗?

我的应用程序context.xml中包含以下内容

    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="*" rollback-for="Throwable"/>
    </tx:attributes>
</tx:advice>
<aop:config>
    <aop:pointcut id="serviceMethods" expression="execution(* com.company.service..*.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
</aop:config>

让spring创建您的会话并管理您的交易。 TransactionSynchornizationManager是您通常不应该使用的东西。

Session.save应该为瞬态实例分配一个标识符,并通过执行插入操作将其持久化。 我很惊讶它没有在您的第一个服务电话中这样做。

而且,由于NPE出现在您的服务调用中,因此该事务将回滚(因为您使用<tx:method name="*" rollback-for="Throwable"/> ),这可以解释后续调用之间的一些差异和失败的。 我不知道您的前两行代码应该做什么,但是正如Bozho所说,您不应自己将资源绑定到TransactionSynchronizationManager。 这是春天的责任。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM