2017-05-08 9 views
1

webserviceに情報を抽出してデータベースに保存するプロセスを作成する必要があります。しかし、このプロセスは非常に時間がかかるため、バックグラウンドで実行したいと考えています。バックグラウンドスレッドスローHibernateException - "スレッドにバインドされているHibernateセッションがありません"

現在のところ、UIのボタンによって呼び出されるProcessHandlerがあります。このハンドラは、バックグラウンドでプロセスを実行するThreadを作成します。ただし、メッセージNo Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one hereHibernateExceptionを取得しています。私は設定xmlファイルのいずれかでProcessHandlerを定義した

は、次のように(これは非常に一般的な定義である)(いくつかある):ProcessHandlerインサイド

<bean class="com.project.ProcessHandler" parent="parentHandler" /> 

は、このプロセスを呼び出すためのコードも非常にありますジェネリック:

Thread t = new Thread(new WorkerThread(alphaManager, bravoManager, charlieManager)); 
t.start(); 

これはWorkerThreadの現在の実装である:

public class WorkerThread implements Runnable { 

    private Manager alphaManager; 
    private Manager bravoManager; 
    private Manager charlieManager; 

    public WorkerThread() { 
     this.alphaManager = null; 
     this.bravoManager = null; 
     this.charlieManager= null; 
    } 

    public WorkerThread(Manager alphaManager, Manager bravoManager, Manager charlieManager) { 
     this.alphaManager = alphaManager; 
     this.bravoManager = bravoManager; 
     this.charlieManager= charlieManager; 
    } 

    @Override 
    public void run() { 
     // code to query webservice and extract data... 

     saveToDbMethod(data); 
    } 

    @Transactional(propagation = Propagation.REQUIRED) 
    private void saveToDbMethod(String data) { 
     // code to process data... 

     alphaManager.save(entityA); 
     bravoManager.save(entityB); 
     charlieManager.save(entityC); 
    } 
} 

デフォルトのコンストラクタは、WorkerThreadを(私のconfig xmlファイルの1つの)Beanとして定義しようとしたときから残っています。

誰でも私にこのトラブルシューティングのヒントを教えてもらえますか?

答えて

1

問題は、スレッドを手動で作成し、それがスプリングマネージドBeanのように動作することを期待していることです。

@Service 
public class Service{ 

    private Manager alphaManager; 
    private Manager bravoManager; 
    private Manager charlieManager; 

    public Service(Manager alphaManager, Manager bravoManager, Manager charlieManager) { 
     this.alphaManager = alphaManager; 
     this.bravoManager = bravoManager; 
     this.charlieManager= charlieManager; 
    } 

    @Transactional(propagation = Propagation.REQUIRED) 
    private void saveToDbMethod(String data) { 
     // code to process data... 

     alphaManager.save(entityA); 
     bravoManager.save(entityB); 
     charlieManager.save(entityC); 
    } 
} 

1)は、依存関係として経営者やその@Transactional方法を持っているでしょうseaparateサービスクラスを作成します。ProcessHandlerとして

が正当な豆で、私は何だろうことは以下のとおりです。

2)ServiceProcessHandlerに注入:

を10

3)最後WorkerThreadServiceを渡す:

public class WorkerThread implements Runnable { 

    private Service service; 

    public WorkerThread(Service service) { 
     this.service = service; 
    } 

    @Override 
    public void run() { 
     // code to query webservice and extract data... 

     service.saveToDbMethod(data); 
    } 
} 

と:

Thread t = new Thread(new WorkerThread(service)); 
t.start(); 

を今すぐあなたの操作は、トランザクション、セッション内でなければなりません。

+0

configにはどのように 'service'を定義する必要がありますか? – ohseekay

+0

私は 'ProcessHandler'の定義のすぐ下に次のように定義しました:' 'しかし、' org.springframework.beans.factory.NoSuchBeanDefinitionException: 「service」という名前のBeanは定義されていません。 – ohseekay

+0

私はこの解決方法に従うことで問題を解決しました。後のコメントでトラブルシューティングのプロセスを詳しく説明します。 – ohseekay

関連する問題