2013-07-24 17 views
6

Spring 3、Hibernate、およびJPAを使用するアプリケーションで作業しています。次のように私は2つのクラスがあります。Springスケジューラ - 循環依存関係がある場合、スケジューリングされたメソッドはトランザクションで開始しません。

@Component 
class Manager { 
    @Autowired 
    Util util; 
} 

@Component 
class Util { 
    @Autowired 
    Manager manager; 

    @Scheduled(fixedDelay = 1 * 60 * 1000) 
    @Transactional(propagation = Propagation.REQUIRED) 
    public void scheduledMethod(){ 
     // Need to update the database in a transaction 
    } 
} 

を次のようにアプリケーションコンテキストから関連する部分は次のようになります。この構成で

<context:component-scan base-package="packageName" /> 
    <tx:annotation-driven /> 
    <bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="defaultPU" /> 
     <property name="dataSource" ref="dataSource" /> 
    </bean> 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 
    <task:annotation-driven executor="executor" scheduler="scheduler"/> 
    <task:executor id="executor" 
     pool-size="10" 
     queue-capacity="10000" 
     rejection-policy="CALLER_RUNS"/> 
    <task:scheduler id="scheduler" pool-size="10"/> 

、私は次の例外を取得し

javax.persistence.TransactionRequiredException: no transaction is in progress 
     at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:978) 
     at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365) 
     at com.sun.proxy.$Proxy43.flush(Unknown Source) 
     at sun.reflect.GeneratedMethodAccessor88.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:601) 
     at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) 
     at com.sun.proxy.$Proxy43.flush(Unknown Source) 

私がUtilクラスからManagerクラスのautowiringを削除すると、正常に動作します。また、デバッグ中に、アプリケーションコンテキストファイルに何らかのエラーがあっても、スケジュールされたメソッドが実行を開始することがわかりました。

従来の理由から、私は循環的な依存関係を避けることはできません。 循環依存の場合にこの例外が発生する理由を誰かが助けることができますか?

+0

をachiveすることができます。 Spring JIRAにバグを送ることができると思います。少なくとも、この動作は文書化されていません。この問題を回避するには、スケジュールされたメソッドを使用して別のBeanからトランザクションメソッドを起動するか、トランザクションメソッドの代わりにTransactionTemplateを使用します。 –

答えて

0

あなたは(ポストプロセッサが順序付けられているため)AOPプロキシクリエータの後に起動するようになっていても、その予定の後処理工程裸豆と思われるこの使用@PostConstruct

@Component 
class Manager { 

    Util util; 

    public void setUtil(Util util) { 
     this.util = util; 
    } 
} 


@Component 
class Util { 
    @Autowired 
    Manager manager; 

    @PostConstruct 
    public void init(){ 
     manager.setUtil(this); 

    } 

    @Scheduled(fixedDelay = 1 * 60 * 1000) 
    @Transactional(propagation = Propagation.REQUIRED) 
    public void scheduledMethod(){ 
     // Need to update the database in a transaction 
    } 
} 
関連する問題