2011-10-14 8 views
3

私は春の教育を続けています。現在私は、Spring 3にもたらすアノテーションやいくつかのことを学びたいと思っています。そのため、DBに接続してフォームを通してデータを入れたり、レコードを表示できるミニWebアプリケーションがあります。すべてうまく動作します。私は@TransactionalとしてマークしたサービスBeanを自動的に検出するようにSpringを試してみることにしましたが、これを実行するとアプリケーションがDBに保存されなくなります。したがって:Spring @Transactionalは他のアノテーションでは機能しませんか?

@Transactional 
public class ReservationServiceImpl implements ReservationService { 

が動作します。私はspringcourt-data.xmlファイルにこのクラスのbean宣言を持っています。問題はありません。私がこれを行うとき:

@Transacational 
@Service("reservationService") 
public class ReservationServiceImpl implements ReservationService { 

それはもう機能しません。 springcourt-servlet.xmlファイルには

<context:component-scan base-package="com.springcourt" /> 

があります。だから誰も私が何をねじっているのか教えてもらえますか?私が行うことは、このクラスに別の注釈を追加し、xmlファイルからBean定義を削除するだけで、データはDBに保存されなくなります。私はまだDBからレコードとデータを照会できますが、明らかに自動検出されたサービスBeanを使用しています。ここで

は、設定ファイルは以下のとおりです。

springcourt-servlet.xml 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 

<context:component-scan base-package="com.springcourt" /> 

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> 

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="webBindingInitializer"> 
     <bean class="com.springcourt.web.ReservationBindingInitializer" /> 
    </property> 
</bean> 

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="prefix" value="/WEB-INF/jsp/"/> 
    <property name="suffix" value=".jsp"/> 
</bean> 
</beans> 

そして:

springcourt-data.xml 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:p="http://www.springframework.org/schema/p" 
xsi:schemaLocation=" 
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter"> 
     <bean 
      class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="database" value="MYSQL" /> 
      <property name="showSql" value="true" /> 
     </bean> 
    </property> 
</bean> 

<bean id="dataSource" 
     class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="url" value="jdbc:mysql://localhost:3306/test" /> 
    <property name="username" value="root" /> 
    <property name="password" value="admin" /> 
    <property name="initialSize" value="5" /> 
</bean> 

<bean id="transactionManager" 
    class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

<tx:annotation-driven /> 

<bean id="reservationService" class="com.springcourt.service.ReservationServiceImpl"/> 
</beans> 
+0

カップルなぜあなたはコンテキストでreservationServiceを宣言してもサービス@それに注釈を付けている、また、第二のコンテキストにコンテキストコンポーネントのスキャンを追加あなたの投稿に "And"の​​後ろに記載されているファイル。 –

+0

"@Transacational"に入力ミスがあります。それを "@トランザクション"に修正してください – buddamus

答えて

3

@Serviceを使用し、Beanをスキャンするコンポーネントは、ディスパッチャサーブレット(mvc)によって作成されたコンテキストによって作成されます。トランザクション:注釈駆動型はルートアプリケーションコンテキストで定義されているため、サーブレットコンテキストのBeanには適用されません。これを確認するには、@Serviceを削除し、Bean定義をサーブレットコンテキストファイルに移動します。同じ結果が表示されます。

どこコンポーネントのスキャンを使用しない場合など - Beanが、ルートアプリケーションコンテキストのXMLで定義されています。

修正点は、Webレイヤーのコンポーネントスキャンタグを変更することです。別の基本パッケージを使用するか、または包含/除外フィルターを使用するかのいずれかで、Webレイヤークラスのみが含まれます。他のBeanのルートアプリケーションコンテキストに別のコンポーネントスキャンを追加します。

OpenEntityManagerInViewInterceptor/Filterが設定されている可能性があるため、クエリが機能している可能性があります。

+0

いいえ、OpenEntityManagerInViewInterceptorはありません。少なくとも明示的に宣言しているわけではありません。しかし、私はあなたが言ったことを試みました、そして、それは働いたようです。私は、spring-court-data.xmlファイルでサービスパッケージのコンポーネントスキャンタグを宣言し、もう一方をspring-court-servlet.xmlファイルに残しました。 Prasanna Talakantiのようなものは、私が推測している以上に言っていました。私は、これらのファイルの分離がどのように異なるタグに影響を与えるかを完全に理解していません。 – cardician

+0

もう一度コメントしてください。 spring-court - *。xmlファイルからすべての設定を削除し、applicationContext.xmlに配置しました。を使用するだけで正常に動作します。だから問題は明らかに、2つのファイルの間で物事がどのように分割されたかと関係していました。もし誰かが私にこの階層の仕組みについての明確な説明を教えることができれば、感謝します。ありがとう。 – cardician

+0

春のmvcドキュメント - http://static.springsource.org/spring/docs/2.5.x/reference/mvc.htmlのセクション13.2を参照してください。すべてを1つのファイルにまとめることはできますが、お勧めしません。 – gkamal

1

あなたが同じBeanを経由してDBを照会することができますので、あなたの@Transactional作品か、少なくともで(例外が頻繁になるだろう休止状態)。ほとんどの場合、セーブ操作でトランザクション・ロールバックを引き起こす実行時例外が発生します。何が例外であるかを調べ、そこから行ってみてください。


更新

@Transactionalはメソッドの内部から適用され、印刷スタックトレースを得たかどうかを確認します。トランザクション・アスペクトが機能することを意味する多くのトランザクション・インターセプタで長いスタック・トレースが表示される場合。

+0

もちろん、私は間違っているかもしれませんが、それはまったく正確ではないと私は信じています。トランザクションタグを完全に削除して、依然としてDBからクエリを実行し、データを取得できます。私の理解は@TransactionalはDBへのデータの永続性にのみ影響します。また、エラーはありません。コードをステップ実行してTry/Catchブロックに配置することができ、私には見える例外もスローされません。 – cardician

+0

あなたは、永続性のためにどのようなテクノロジーを使用しているかは言及していません。それはプレーンなJDBCですか?この場合、それぞれの文を自分のトランザクションで実行できるので(設定に応じて) '@ Transactional'は必要ありません。それは読み書きにも同様に当てはまります。 '@ Transactional'がメソッドの中からスタックスタックトレースを適用したかどうかを調べる。トランザクション・アスペクトが機能することを意味する多くのトランザクション・インターセプタで長いスタック・トレースが表示される場合。データがエラーなく永続化されないとはほとんど想像もできません。 –

+0

申し訳ありませんが、私は何かを忘れて驚いていません。私はJPAを使ってMySQLデータベースに接続しているHibernateを使っています。上記の設定ファイルを追加しました。また、何もスローされていない場合は、スタックトレースから何も印刷できますか?私はそれと一緒に遊んで、私は推測を参照してください。 – cardician

0

、孤立して裁判所-data.xmlの-春にこの

  • は、コンテキストコンポーネントのスキャンを追加

    <context:component-scan base-package="com.springcourt" /> 
    
  • テストサービスを試してみてください。この

    @RunWith(SpringJUnit4ClassRunner.class) 
    @ContextConfiguration(locations={"classpath:springcourt-data.xml"}) 
    @Transactional 
    public class ReservationServiceImplTest() 
    { 
        @Autowired 
        ReservationServiceImpl service; 
    
        @Test 
         public void validateContext() 
         { 
          Assert.assertNotNull(service); 
         } 
    
         @Test 
         @Rollback(false) 
         public void save() 
         { 
         service.save(data); 
         } 
    
    } 
    
    のようなJUnitテストにいくつかのものを作成します。
+0

答えをありがとう。それは具体的に動作していないようだが、gkamalの答えと組み合わされて問題を解決したようだ。私は明らかに構成ファイルの階層を理解していません。私が行ったように分割されていて、私が読んだ本は実際にはそれを全くカバーしていません。 – cardician

1

私は同じ問題を抱えています。第一

あなたのコンテキストを区切る必要があります:コンポーネント・スキャンをウェブとデータレベルに、次のように:

<!--in springcourt-servlet.xml --> 
<context:component-scan base-package="com.springcourt.web" /> 

<!--in springcourt-data.xml --> 
<context:component-scan base-package="com.springcourt.dao" /> 

第二アドオンをspringcourt-data.xmlにする

<aop:aspectj-autoproxy/> 

を、私はそれがことを願っています便利な

0

あなたが持っているものに代わるものは、次のものを使うことです: `

@Configuration 
@EnableAspectJAutoProxy(proxyTargetClass=true) 
public class AppConfig { 
    (...) 
} 

あなたがしなければならないことは、すべてを同じスコープに注入することです。 1つの方法は、前述のようにApplicationContext xmlを変更することです。もう1つは、CGLIBをSpringプロキシのように使用して、サブクラスベースのプロキシを取得し、Beanの実装と定義を記述することです。

さらに読書:物事の