2011-06-20 7 views
5

私は、テーブル名、いくつかのデータを持つXMLファイルを設定したい単純なBeanを作成しています。そのため、アプリケーションの起動時にテーブルが空であれば、そのデータで初期化されます。私は、単純なSQLクエリを使用することにしましたが、それが言うので、私は、SessionFactoryのからセッションを取得することはできません。SpringでこのBeanを@Transactionalにすることができないのはなぜですか?

Error creating bean with name 'vecchiOrdiniFiller' defined in ServletContext resource [/WEB-INF/spring/servlet-context.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

をしかし、これは(サービスに非常に似ている)の構成である。

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

<tx:annotation-driven /> 

<bean id="ordiniVecchioSistemaLoader" class="it.jsoftware.jacciseweb.assistenza.common.ExcelXmlDataLoader"> 
    <property name="xmlFileName" value="WEB-INF/data/daticlientijaccisemarco.xml"></property> 
</bean> 

<bean id="vecchiOrdiniFiller" class="it.jsoftware.jacciseweb.assistenza.common.BaseTableFiller" init-method="init"> 
    <property name = "sessionFactory" ref = "mySessionFactory"></property> 
    <property name="loader" ref="ordiniVecchioSistemaLoader"></property>  
    <property name="tableCreationString" value="CREATE TABLE `vecchiordini` ( `ID` INT(11) NOT NULL AUTO_INCREMENT, `codicejazz` VARCHAR(255) DEFAULT NULL, `progressivolicenza` INT(11), `codicearticolo` VARCHAR(255) DEFAULT NULL, `rivenditore` VARCHAR(255) DEFAULT NULL, `cliente` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`ID`)) ENGINE=INNODB DEFAULT CHARSET=utf8"></property> 
    <property name="table" value="vecchiordini"></property> 
    <property name="tableColumns"> 
     <list> 
      <value>codicejazz</value> 
      <value>progressivolicenza</value> 
      <value>codicearticolo</value> 
      <value>rivenditore</value> 
      <value>nomecliente</value> 
     </list> 
    </property> 
    <property name="loaderColumns"> 
     <list> 
      <value>clicod</value> 
      <value>licsmatricola</value> 
      <value>artcod</value> 
      <value>rivenditore</value> 
      <value>cliente</value> 
     </list> 
    </property> 
</bean> 

と@Transactionalでinit()メソッドに注釈を付けました。しかし、それは、トランザクションを開始しないと私はエラーを取得する:

@Transactional 
public void init() throws Exception { 
    logger.info("BaseTableFilter per tabella: " + table + ", usando: " 
    + loader.getSourceName()); 

    Session session = dao.getSession(); 
    Transaction tx = session.beginTransaction(); 
    ... 

は、なぜそれが動作しませんか?

答えて

15

init-methodまたは@PostConstruct注釈付きメソッドはプロキシされていないため、@Transactionalを使用することはできません。あなたのサービスで@Transactionalを使うべきです、なぜそれはあなたには適していませんか? はSpringSource Jiraより引用:

This is as defined, actually: init methods (such as @PostConstruct methods) are always called on the target instance itself. The proxy will only be generated once the target instance has been fully initialized... In other words, the @Transactional proxy isn't even created at the point of the @PostConstruct call yet.

Switching to mode="aspectj" would help since it weaves the target class directly, in which case the init method will have been modified for transactional awareness at the time of the container init call already.

I guess at the very minimum, we should document the limitations of @Transactional on proxies more clearly - and point out where mode="aspectj" might be a solution.

述べたように、あなたがmode="aspectj"を試すことができず、むしろ、あなたが私の意見では、あなたのデザインを確認する必要があります。

+1

関連リンクの「+1」をクリックします。 –

+0

私は自分のデザインを見直しました...私は私のサービスへの参照を置くだけで、それだけです。なぜ私はこれを避けたいのですか?私のサービスからでも真の独立したライブラリを作って、それを再利用したいと思っていたので、おそらくは、GPLのもとでオンラインにすることもできました...とにかく、@Donalは当初からこれをやる方が簡単でした。できるだけ巧妙な新しいソリューションに向けて、新しいものや有用なものを得ることは決してありません。 – gotch4

+0

今日はこの5時間を失った。もし私が質問と回答をアップアップすることができれば1000回! – HDave

2

initメソッドをトランザクションにすることはできません。しかし、そこから別のサービスの別のトランザクションメソッドを呼び出すことができます。

+0

私はDAOを直接呼び出してDAOメソッドをトランザクションにすることができます(これはばかげているかもしれませんが、今まではサービスメソッドをトランザクションにしていたので、忍耐を与えてください)。 – gotch4

+2

できますが、通常はしないでください。 – Bozho