2

我厌倦了解决这个问题所以如果有人能建议我哪里错了,我将不胜感激。

问题是我在我的 Spring MVC 项目中使用Spring-BatchHibernate Full-Text Search。所以从批处理作业 Tasklet 我调用以下代码:

 A a=aDao.merge(a);
 b.setA(a);
 bDao.save(b);

在对这些实体进行保存更新时,我遇到了一个异常,堆栈跟踪如下:

org.springframework.orm.hibernate3.HibernateSystemException: Error while indexing in Hibernate Search (before transaction completion); nested exception is org.hibernate.HibernateException: Error while indexing in Hibernate Search (before transaction completion)
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:690)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264)
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
    at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: org.hibernate.HibernateException: Error while indexing in Hibernate Search (before transaction completion)
    at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:175)
    at org.hibernate.engine.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:543)
    at org.hibernate.engine.ActionQueue.beforeTransactionCompletion(ActionQueue.java:216)
    at org.hibernate.impl.SessionImpl.beforeTransactionCompletion(SessionImpl.java:571)
    at org.hibernate.jdbc.JDBCContext.beforeTransactionCompletion(JDBCContext.java:250)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:138)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
    ... 21 more
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
    at org.hibernate.search.util.HibernateHelper.unproxy(HibernateHelper.java:62)
    at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:394)
    at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:481)
    at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:481)
    at org.hibernate.search.engine.DocumentBuilderIndexedEntity.getDocument(DocumentBuilderIndexedEntity.java:379)
    at org.hibernate.search.engine.DocumentBuilderIndexedEntity.createAddWork(DocumentBuilderIndexedEntity.java:317)
    at org.hibernate.search.engine.DocumentBuilderIndexedEntity.addWorkToQueue(DocumentBuilderIndexedEntity.java:295)
    at org.hibernate.search.engine.WorkPlan$PerEntityWork.enqueueLuceneWork(WorkPlan.java:445)
    at org.hibernate.search.engine.WorkPlan$PerClassWork.enqueueLuceneWork(WorkPlan.java:246)
    at org.hibernate.search.engine.WorkPlan.getPlannedLuceneWork(WorkPlan.java:150)
    at org.hibernate.search.backend.WorkQueue.prepareWorkPlan(WorkQueue.java:134)
    at org.hibernate.search.backend.impl.BatchedQueueingProcessor.prepareWorks(BatchedQueueingProcessor.java:124)
    at org.hibernate.search.backend.impl.PostTransactionWorkQueueSynchronization.beforeCompletion(PostTransactionWorkQueueSynchronization.java:89)
    at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:172)
    ... 27 more

我没有弄错。我正在使用org.springframework.orm.hibernate3.HibernateTransactionManager,我的 Spring 版本是 3.2 Hibernate 核心版本是 3.6 final。

注意:这个异常经常发生,但是当我创建一个新表或使用新数据库时,它就像魅力一样工作,所有修改/插入都在数据库中正确反映。有人可以解释一下这种行为还是我做了一些可疑的事情。

如果您需要更多详细信息,请告诉我。

谢谢你。

代码更新:

<batch:job-repository id="jobRepository"
                          data-source="myJNDI"
                          transaction-manager="transactionManager"
                          isolation-level-for-create="READ_COMMITTED"
                          max-varchar-length="2500"
                          lob-handler="defaultLobHandler"
    />



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

像这样,我在 applicationContext.xml 中为 Spring-Batch 配置事务管理器。我尝试通过手动提交事务手动打开和关闭会话,但异常保持不变。是的,我已将我的方法注释为 @Transactional。

4

1 回答 1

1

我发现问题的根本原因是Spring 的声明式事务管理。Spring Batch in Action 参考:

  • 为您的批处理应用程序禁用 Spring 的声明性事务——不要使用 tx:annotation-driven 元素或任何与声明性事务管理相关的 XML 配置。

  • 如果声明性事务开启,请小心使用传播级别——如果您从 Spring Batch 作业调用事务类,由于传播级别,Spring 的事务传播可能会干扰 Spring Batch 事务。REQUIRES_NEW 传播级别通常会导致问题,因为应用程序代码在其自己的事务中运行,独立于 Spring Batch 事务。

以下是避免 Spring Batch 管理的事务和 Spring 管理的事务之间发生冲突的指南:

交易图

于 2014-02-17T09:15:13.017 回答