1

私は同様の問題を探しまし たが、これに対する解決策を見つけることができませんでした:

私はSpring Data JPAアプリケーションを持っており、トランザクションを実行しようとするたびにjavax.persistence.TransactionRequiredException: no transaction is in progress.

Transaction Manager または Entity Manager Factory と関係があると思いますが、はっきりとはわかりません。

コンテキスト ファイルはここにあります(最新のチェックインはここにあります) が、重要な部分は次のとおりです。

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

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

<bean id="dataSourceMySQL" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/dbname"/>
    <property name="username" value="user"/>
    <property name="password" value="pass"/>
</bean>

<jpa:repositories base-package="com.simplecash.dal.repository" />

サンプルのリポジトリがここにあり、リポジトリ ファクトリをここに作成しましたが、これが必要かどうかはわかりません...次に、ここで使用します(34 行目)。

public void populateWithTestData() {

    Bank bank = new Bank();
    bank.setName("ContentName");
    bank.setCode("ContentCode");

    RepositoryFactory.getEntityManager().getTransaction().begin();
    BankRepository bankRepository = RepositoryFactory.getRepository(BankRepository.class);
    bankRepository.save(bank);
    bankRepository.flush();
    RepositoryFactory.getEntityManager().getTransaction().commit();
}

上記のいくつかの点が間違っていますが、修正しようとしましたが、できません。

  1. Begin および Commit トランザクションは明示的です。
  2. bankRepositoryである必要がありますが@Autowired、それを行うと が得られnullます。ただし、このテストケースでは Autowired で動作します。

誰かが同様の問題に直面し、何が起こっているのか知っていますか? これを読んでくれてありがとう。この質問に対する答えが他の人々に役立つことを願っています。

4

4 に答える 4

3

ここで提供される両方の回答は良い点を提供します(プロキシされたBeanを取得するためのインジェクションとトランザクションアノテーションの使用)が、アノテーション駆動型トランザクション(@Transactional)が機能するには、以下を追加する必要があると確信しています。 xml構成:

<tx:annotation-driven transaction-manager="transactionManager"/>

また、beans-tagにtx-namespaceを追加してください。

<beans
  <!-- SNIP, other namespaces -->
xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="
  <!-- SNIP, other locations -->
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
于 2012-01-14T08:52:22.663 に答える
2
  • 開始トランザクションとコミットトランザクションは明示的です。

SpringがリポジトリBean(たとえばBankRepository)で行うことは、その周りにプロキシを作成し、他の共同作業者(あなたの場合はです)に注入DatabaseManagerDAOする準備ができています。ただし、自分でオブジェクトを作成する場合は、次のようにします。

BankRepository bankRepository = RepositoryFactory.getRepository(BankRepository.class);

予想されるSpringのプロキシ(すでにトランザクション管理を行っている)の代わりに、即時宣言以外のことを認識しない単純なオブジェクトを取得しています。

代わりに行う必要があるのは、 Springに配管を任せて、bankRepositoryBeanを注入することDatabaseManagerDAOです(ただし、DAOとリポジトリの両方が必要だとは思いませんが、これらの用語は実際には同じことを意味します:)

  • ここにリポジトリファクトリがありますが、必要かどうかはわかりません...

別の抽象化の必要はありません。必要なコンポーネントにBeanとして注入するだけです。

  • bankRepositoryあるべきですが@Autowired、そうすると私は得nullます。ただし、このテストケースでは、自動配線されて機能します。

それが機能する場合は、「bankRepository」Beanについて知っているAbstractTransactionalJUnit4SpringContextTests、を使用してテストを実行するため、自動配線されます。あなたの中には、自動配線もセッターもありません。実際、工場から手動で作成しています。DatabaseManagerDAObankRepository

コメントに答えるために編集

XML構成で実際に行われること=>パッケージをスキャンし、インターフェースとして注釈が付けられているか、インターフェースを実装しjpa:repositoriesているコンポーネントごとにSpringBeanを作成します。@RepositoryRepository

BankRepositoryそれを念頭に置いて、でリポジトリを使用するためにすべきことは、DatabaseManagerDAOそれを注入することです。あなたは「自動配線」を介してそれを行うことができます:

@Service
public class DatabaseManagerDAO {

    @Autowired
    BankRepository bankRepository;
    ... 
}

工場で手動で作成する代わりに。

繰り返しDatabaseManagerDAOますが、あなたの場合はおそらくサービス(@Service)であり、ではありませんがDAO、それを決定するのはあなたに任せます。

自動配線を機能させるには、aもSpringによってロードされる必要があることに注意してください。したがって、パッケージスキャンするときに DatabaseManagerDAOSpringアノテーション(@Service/ )の1つが含まれていることを確認してください(例)。@Component<context:component-scan base-package="org.example"/>

于 2012-01-14T06:17:44.750 に答える
2

あなたの設定では、トランザクションは JTA によって管理されているため、明示的に開始/停止することはできません (つまり、em.getTransaction().begin() は機能しません)。次のように、アノテーションを介して特定のメソッドを (JTA 管理の) トランザクションの一部にすることを Spring に伝えてみてください。

@Transactional
public void populateWithTestData() {
   //...    
}
于 2012-01-13T21:51:21.703 に答える
2

と を組み合わせたときにも同様の問題がspring-batchありspring-jpaました。私のバッチ XML には、次の行がありました。

<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>

JPA が必要なため、エラーが発生しましたPlatformTransactionManager

于 2013-03-10T18:55:35.287 に答える