2

私はこの問題に頭を悩ませるのにうんざりしているので、誰かがどこが間違っているかを教えてくれたら、感謝します.

問題は、Spring MVC プロジェクトでSpring-BatchHibernate 全文検索を使用していることです。そのため、バッチ ジョブ 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 最終版です。

注:この例外は頻繁に発生しますが、新しいテーブルを作成したり、新しいデータベースを使用したりすると、魅力的に機能し、すべての変更/挿入がデータベースに適切に反映されます.

詳細が必要な場合は教えてください。

ありがとうございました。

コードの更新:

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

このように、Spring-Batch の applicationContext.xml でトランザクション マネージャーを構成しています。また、手動でトランザクションをコミットしてセッションを手動で開いたり閉じたりしてこれを実行しようとしましたが、例外は同じままです。

4

1 に答える 1

1

問題の根本的な原因は、Spring の Declarative Transaction Managementであることがわかりました。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 に答える