3

だから私の春の教育は続きます。現在、私はいくつかの注釈とそれらが Spring 3 にもたらすものを学ぼうとしています。そのため、DB に接続し、フォームを介して情報を入力し、レコードなどを表示できるミニ webapp を取得しました。すべて正常に動作します。@Transactional としてマークしたサービス Bean を Spring に自動検出させることにしましたが、そうするとアプリが DB に保存されなくなります。そう:

@Transactional
public class ReservationServiceImpl implements ReservationService {

それは機能します。springcourt-data.xml ファイルに、このクラスの Bean 宣言があります。問題はありません。私がこれを行うとき:

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

それはもはや機能しません。そして、私は持っています

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

springcourt-servlet.xml ファイル内。それで、誰かが私が台無しにしていることを教えてもらえますか? このクラスに別の注釈を追加し、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>
4

5 に答える 5

3

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

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

修正は、別のベース パッケージを使用するか、包含/除外フィルターを使用して、Web レイヤー クラスのみを含めるように Web レイヤーの component-scan タグを変更することです。他の Bean のルート アプリケーション コンテキストに別のコンポーネント スキャンを追加します。

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

于 2011-10-14T20:29:41.703 に答える
1

私は同じ問題を抱えており、それを解決します。

まず、次のように、context:component-scan を Web およびデータ レベルに分離する必要があります。

<!--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 への 2 回目の追加

<aop:aspectj-autoproxy/>

お役に立てば幸いです

于 2013-07-30T06:51:59.670 に答える
1

同じ Bean を介して DB にクエリを実行できるため、@Transactional動作するか、例外が発生することがよくあります (少なくとも Hibernate では)。ほとんどの場合、保存操作で、トランザクションのロールバックを引き起こす実行時例外が発生します。例外が何であるかを調べて、そこから進んでください。


アップデート

適用されたかどうかを確認する@Transactionalには、メソッド内からスタック トレースを出力します。多くのトランザクション インターセプターを含む長いスタック トレースが表示される場合は、トランザクションの側面が機能していることを意味します。

于 2011-10-14T18:58:42.233 に答える
0

これを試して

  • コンテキスト コンポーネント スキャンを spring-court-data.xml に追加します。

      <context:component-scan base-package="com.springcourt" />
    
  • 単独でサービスをテストする、JUNIT テストを作成する、このようなものを作成する

    @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);
          }
    
    }
    
于 2011-10-14T20:21:28.217 に答える
0

あなたが持っているものの非常に良い代替手段は、次を使用することです: `

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

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

参考文献:

于 2016-05-09T18:52:19.967 に答える